- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 Glide 加载图像、调整图像大小并通过 SimpleTarget<Bitmap>
将其保存到文件中.这些图像将上传到 Amazon S3,但这不是重点。我在上传之前调整图像大小,以尽可能多地节省用户的带宽。因为我的应用程序需要一张 1024 像素宽的图像就足够了,所以我使用以下代码来实现:
final String to = getMyImageUrl();
final Context appCtx = context.getApplicationContext();
Glide.with(appCtx)
.load(sourceImageUri)
.asBitmap()
.into(new SimpleTarget<Bitmap>(1024, 768) {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
try {
FileOutputStream out = new FileOutputStream(to);
resource.compress(Bitmap.CompressFormat.JPEG, 70, out);
out.flush();
out.close();
MediaScannerConnection.scanFile(appCtx, new String[]{to}, null, null);
} catch (IOException e) {
e.printStackTrace();
}
}
});
它几乎完美地工作,但生成的图像的大小不是 1024 像素宽。使用尺寸为 4160 x 2340 像素的源图像对其进行测试,结果保存图像的尺寸为 2080 x 1170 像素。
我试过使用 width
和 height
传递给 new SimpleTarget<Bitmap>(350, 350)
的参数使用这些参数,生成的图像尺寸为 1040 x 585 像素。
我真的不知道该怎么做才能让 Glide 尊重传递的维度。事实上,我想按比例调整图像的大小,以便将较大的尺寸(宽度或高度)限制为 1024 像素,而较小的尺寸相应地调整大小(我相信我必须找到一种方法来获取原始图像尺寸,然后将宽度和高度传递给 SimpleTarget
,但为此我需要 Glide 尊重传递的宽度和高度!)。
有人知道发生了什么事吗?我正在使用 Glide 3.7.0。
由于这个问题本身可能对尝试使用 Glide 调整大小和保存图像的人有用,我相信提供我的实际“解决方案”符合每个人的利益,该解决方案依赖于新的 SimpleTarget
。自动保存调整大小的图像的实现:
import android.graphics.Bitmap;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileTarget extends SimpleTarget<Bitmap> {
public FileTarget(String fileName, int width, int height) {
this(fileName, width, height, Bitmap.CompressFormat.JPEG, 70);
}
public FileTarget(String fileName, int width, int height, Bitmap.CompressFormat format, int quality) {
super(width, height);
this.fileName = fileName;
this.format = format;
this.quality = quality;
}
String fileName;
Bitmap.CompressFormat format;
int quality;
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
try {
FileOutputStream out = new FileOutputStream(fileName);
bitmap.compress(format, quality, out);
out.flush();
out.close();
onFileSaved();
} catch (IOException e) {
e.printStackTrace();
onSaveException(e);
}
}
public void onFileSaved() {
// do nothing, should be overriden (optional)
}
public void onSaveException(Exception e) {
// do nothing, should be overriden (optional)
}
}
使用起来很简单:
Glide.with(appCtx)
.load(sourceImageUri)
.asBitmap()
.into(new FileTarget(to, 1024, 768) {
@Override
public void onFileSaved() {
// do anything, or omit this override if you want
}
});
最佳答案
经过一夜安眠,我终于明白了!我在 Glide 的 github 页面上偶然发现了一个有答案的问题,但我没有意识到:我在解释中遗漏了一些东西,在休息 10 小时后我现在完全理解了。永远不要低估 sleep 的力量!但我离题了。这是在 Glide's Github issue tracker 上找到的答案:
Sizing the image usually has two phases:
- Decoding/Downsampler read image from stream with inSampleSize
- Transforming/BitmapTransformation take the Bitmap and match the exact target size
The decoding is always needed and is included in the flow, the default case is to match the target size with the "at least" downsampler, so when it comes to the transformation the image can be downsized more without quality loss (each pixel in the source will match at least 1.0 pixels and at most ~1.999 pixels) this can be controlled by asBitmap().at least|atMost|asIs|decoder(with downsampler)
The transformation and target size is automatic by default, but only when using a ViewTarget. When you load into an ImageView the size of that will be detected even when it has match_parent. Also if there's no explicit transformation there'll be one applied from scaleType. Thus results in a pixel perfect Bitmap for that image, meaning 1 pixel in Bitmap = 1 pixel on screen resulting in the best possible quality with the best memory usage and fast rendering (because there's no pixel mapping needed when drawing the image).
With a SimpleTarget you take on these responsibilities by providing a size on the constructor or via override() or implementing getSize if the sizing info is async-ly available only.
To fix your load add a transformation: .fitCenter|centerCrop(), your current applied transformation is .dontTransform() (Answer by Róbert Papp)
因为这个,我对这个答案感到困惑:
With a SimpleTarget you take on these responsibilities by providing a size on the constructor or via override() or implementing getSize if the sizing info is async-ly available only.
由于我超过了尺码,所以我认为我已经得到了这个尺寸,应该尊重这样的尺码。我错过了这个重要的概念:
- Decoding/Downsampler read image from stream with inSampleSize
- Transforming/BitmapTransformation take the Bitmap and match the exact target size
还有这个:
To fix your load add a transformation: .fitCenter|centerCrop(), your current applied transformation is .dontTransform()
现在我把它拼凑起来了,这是有道理的。 Glide 只是对图像进行下采样(如 Róbert 所解释的调整图像大小流程的第一步),这给出了具有近似尺寸的图像。不得不说Glide在这方面是非常聪明的。通过在调整大小之前使用下采样方法,可以避免在内存中使用不必要的大位图并提高调整大小的质量,因为下采样到精确大小会损害太多“重要”像素!
由于我没有对这个加载管道应用任何转换,因此在第一步(下采样)中停止了尺寸调整流程,并且生成的图像只有我预期目标尺寸的近似尺寸。
为了解决这个问题,我只是应用了一个 .fitCenter()
转换,如下所示:
Glide.with(appCtx)
.load(sourceImageUri)
.asBitmap()
.fitCenter()
.into(new FileTarget(to, 1024, 768) {
@Override
public void onFileSaved() {
// do anything, or omit this override if you want
}
});
生成的图像现在具有 1024 x 576 像素的尺寸,这正是我所期望的。
Glide 是一个非常酷的库!
关于java - 滑动加载到 SimpleTarget<Bitmap> 中不遵守指定的宽度和高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37847987/
这是在我的 MainActivity 中用作 BroadcastReceiver 的代码 mRegistrationBroadcastReceiver = new BroadcastRecei
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我想在大部分时间隐藏 UISearchBar,只在用户需要时调用它来显示。 我在 Interface Builder 中放置了一个 UISearchBar 并将其隐藏在 View 后面,当用户单击按钮
我有一个包含 CCMenuItemImage 的菜单(“myMenu”)。我希望此菜单能够检测手指滑动并相应地滑动。 我的问题是 CCMenuItemImage 似乎吸收了触摸事件。当用户触摸 CCM
我正在寻找一个简单的 jQuery 或 Javascript 解决方案,以使导航侧边栏在用户向下滚动页面时顺利跟随用户。像这里一样:http://ucon-acrobatics.com/shop/ 任
我有一个 ListView 控件来显示项目,我想提供一个滑动/滑动手势来选择一个项目。我用 GestureRecognizer类来识别交叉滑动手势,但我还想通过水平移动选择的项目来为这个手势设置动画。
我想将 String 行标记化为标记(存储到 String 表中),并且我只能使用 java.io.*它是为了实现一个计算器。 例如:第一行:1+2+3第二行:1+ 2*3(标记之间有空格) 进入表{
我有一个 ListView 控件来显示项目,我想提供一个滑动/滑动手势来选择一个项目。我用 GestureRecognizer类来识别交叉滑动手势,但我还想通过水平移动选择的项目来为这个手势设置动画。
我有一个导航栏,当单击菜单图标时,它将滑入“#secondary-nav”并隐藏“#primary-nav”。然而 jquery 似乎没有显示“#secondary-menu”。下面提供的是 HTMl
这个问题已经有答案了: how to make a sliding up panel like the Google Maps app? (2 个回答) 已关闭 7 年前。 我正在寻找类似的实现,如下
我有 ViewPager(Slide) 和 3 张图片。共有三个图像是通过 Internet 下载的。如果我将图片换到服务器上的另一台服务器上,链接保持不变,但应用程序中的图片没有改变,仍然是缓存中的
我在 gridview 中创建了两个按钮。 我想达到以下目的,但不知道应该用什么方法? 首先我触摸第一个按钮,将显示 toast 1 msg。通过将我的手指滑到第二个按钮而不抬起我的手指,将显示 to
所以我设置了一个小的 jquery 动画,用户将鼠标悬停在容器上一段时间,这会导致容器 split ,然后显示内部信息。 我不希望鼠标一进入容器就开始动画,所以我在动画上放了一个delay()。现在动
这个问题在这里已经有了答案: Simulate swipe with mouse in javascript (5 个答案) 关闭 7 年前。
我希望我的 Sprite 像在冰上一样滑动。因此,如果他在地面上,那么他可以正常行走,但当他接触冰时,他会滑动,直到有东西阻止他。有谁知道如何才能做到这一点?谢谢 最佳答案 像“Sprite Move
我的代码有几个问题:HTML: Bellevue
我正在尝试实现从 fragment1 过渡到 fragment2 的滑动动画。我正在使用 setCustomAnimations 方法。而且我知道我需要使用框架方法来替换 fragment 。 我的代
我不知道你们是否听说过 app chomp,但应用程序中有一个布局,如下图所示。我想知道他们是如何设置的,我将如何使用它来为我自己的应用程序制作类似的东西。有趣的是,当你滑动时,没有像水平 Scrol
我想检测用户何时在一个单元格占据整个屏幕宽度的 collectionView 中向左或向右滑动。是否可以不添加手势识别器。我试过添加手势识别器,但只有当我们将 collectionView 的 scr
我正在尝试开发一个应用程序来复制类似 tinder 的基于滑动的提要。该应用程序的想法与火种非常相似,也具有向右滑动和向左滑动匹配功能。 到目前为止我做了什么-我在 MongoDB 中创建了一个刷卡集
我是一名优秀的程序员,十分优秀!