在Android中裁剪和调整图片大小

3
我正在从磁盘读取图像,并将其显示在ListView的一行中。图像文件比需要在行的ImageView内显示的图像大。由于我需要将位图缓存在RAM中以加快访问速度,因此我希望它们只有ImageViews的大小(85x85 dip)。
现在我正在使用以下代码读取文件:

bitmap = BitmapFactory.decodeFile(file);

并且ImageView负责缩放和裁剪它。

android:scaleType="centerCrop"

据我所知,这会使整个位图保留在内存中(因为我已经缓存了它),这是不好的。
我该如何从ImageView中移除这个职责并在加载文件时进行裁剪+缩放?所有位图都将以85x85 dip显示,并需要进行'centerCrop'处理。
1个回答

6

在加载、裁剪和缩放图片之前,您可以查找图片的尺寸:


BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
Bitmap bmo = BitmapFactory.decodeFile(file.getAbsolutePath(), options);

然后以样本大小加载它:


...
options.inSampleSize = 1/2;
bmo = BitmapFactory.decodeFile(file.getAbsolutePath(), options);

...
 = Bitmap.createScaledBitmap(bmo, dW, dH, false);

不要忘记回收临时位图,否则会出现 OOME(OutOfMemoryError)。


bmo.recycle();

2
我试图避免像这样过于积极地分配和释放内存。此外,在您的示例中,inSampleSize 没有起到任何作用。它需要设置为 > 1 才能起作用,最好是2的幂次方。关于 inSampleSize 的更多信息,请参见:http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize 至于裁剪,我仍然希望自己来处理,而不是让 ImageView 来处理,否则就会浪费内存。 - smith324
如果您有自己的ListAdapter,您可以在getView中设置视图的位图。 - Phyrum Tea
@Phyrum Tea,我没有找到任何有关手动裁剪的信息,所以我想我只能让“ImageView”来处理了。如果我要这样做,那么我可以使用第一个位图的getHeight()和getWidth()来计算正确的位图缩放方式。 - smith324
@Phyrum Tea,还有一个问题,为什么要设置 inJustDecodeBounds?根据我所了解的,它会分配内存但不会实际加载位图。这有什么用处呢?是因为调用更快吗? - smith324
@Phyrum Tea 我自定义的 BaseAdapter 的工作方式是,所有的 ImageViews 在屏幕上显示时必须是相同的大小(出于设计选择),因此需要进行整个裁剪操作。例如,如果一张图片是竖直的,我需要对其进行裁剪而不是缩放(使其拉伸得很奇怪),以便所有的图片都是完美的正方形。目前 centerCrop 可以实现这一点,所以我会保持我的实现方式不变。 - smith324
显示剩余2条评论

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