如何在使用Android通用图像加载器之前调整图片大小以在视图中显示?

7

我成功地将Universal Image Loader库(1.8.3版本)应用到我的应用程序中,并且我正在尝试在显示网格视图项中的图像之前调整图像大小(因为有时图像太大无法缓存在内存中)。

这是我正在尝试的:

...
BitmapFactory.Options resizeOptions = new BitmapFactory.Options();
resizeOptions.inSampleSize = 3; // decrease size 3 times
resizeOptions.inScaled = true;

options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.blank)
.showImageForEmptyUri(R.drawable.no_image)
.cacheInMemory()
.cacheOnDisc()
.decodingOptions(resizeOptions)
.build();
...

由于某些原因,此代码未能将图像缩小三倍。

是否有更好的方法可以按精确的密度调整图像大小?


Novoda ImageLoader会为您自动创建缩略图和分层缓存 :-) https://github.com/novoda/ImageLoader - Blundell
3个回答

22

仔细阅读Java文档:

不会考虑传入选项的Options.inSampleSize。 根据imageScaleType(...)选项,库自己计算最适合的样本大小。

还要查看ImageSizeUtil.defineTargetSizeForView(ImageView imageView, int maxImageWidth, int maxImageHeight),它定义了图像的目标大小:

大小由目标视图参数、配置参数或设备显示尺寸定义。 大小计算算法:

  1. 获取视图的实际绘制getWidth()getHeight()。如果视图尚未绘制,则转到步骤#2。
  2. 获取layout_widthlayout_height。如果它们都没有确切的值,则转到步骤#3。
  3. 获取maxWidthmaxHeight。如果它们都没有设置,则转到步骤#4。
  4. 获取maxImageWidth参数(maxImageWidthForMemoryCache)和maxImageHeight参数(maxImageHeightForMemoryCache)。如果它们都没有设置(等于0),则转到步骤#5。
  5. 获取设备屏幕尺寸。

UIL根据imageScaleTypetargetSize(以及ImageView的scaleType)定义结果Bitmap大小。


imageScaleType和defineTargetSizeForView是用于图像显示的方法,但我需要在将其放入缓存之前缩小图像的解决方案。例如,我有一个网格视图,其中有2列(每个网格项目都是具有120dip边缘内的imageview的正方形视图),并且我在Web服务器上有两个图像变量,分别是120x80 px和640x480 px。小图片对于应用程序的ImageView来说太小了,但是您的库可以很好地缓存它。如果我使用大图片,则ImageView看起来完美,但库无法将图像放入缓存,并且始终在GridView滚动期间重新下载它们。 - John F
@user1328818:“如果我使用大图像,那么ImageView看起来很完美,但库无法将图像放入缓存中…” 你是什么意思? - nostra13
好的,让我来解释一下。如果我使用小图片(120x80),那么您的库会很好地缓存它们,并且在滚动我的网格视图时,这些图片会从缓存中获取而不是从网络上获取。但是,如果我使用大图片(640x480),您的库就不会缓存它们,每次我滚动网格视图时都会重新加载图片。 - John F
UIL 只有在不需要缓存图片时才不会缓存,如果要缓存,请在显示选项中启用 .cacheInMemory() 和 / 或 'cacheOnDisc()'。还需考虑内存缓存大小。内存缓存是有限的,因此如果缓存大小超过限制,则可能会删除某些位图。 - nostra13

14

只需尝试这个:

options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.blank)
.showImageForEmptyUri(R.drawable.no_image)
.cacheInMemory()
.cacheOnDisc()
.decodingOptions(resizeOptions)
.postProcessor(new BitmapProcessor() {
    @Override
    public Bitmap process(Bitmap bmp) {
        return Bitmap.createScaledBitmap(bmp, 300, 300, false);
    }
})
.build();

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接