这是我的用例:
ByteArray ba; // Some value is assigned here
Bitmap bitmap = BitmapFactory.decodeByteArray(ba, 0, ba.length);
由于ByteArray
对象太大,因此在执行以下操作时,第二行会抛出OutOfMemoryError
异常:
BitmapFactory.decodeByteArray(ba, 0, ba.length);
已经尝试:
ByteArray ba; // Some value is assigned here
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; //or whatever value
Bitmap bitmap = BitmapFactory.decodeByteArray(ba, 0, ba.length, options);
此解决方案的问题在于,使用inSampleSize
属性可以避免OutOfMemoryError
异常,但是位图大小(尺寸:宽度x高度)减小了。
相反,我正在寻找类似的东西:
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
在此示例中,降低了位图的质量,但其大小仍然相同。当我在ImageView
中显示它时:
iv.setImageBitmap(bitmap);
它占用的空间与原始空间相同,但质量却降低了一半。
问题是,在我的情况下,我不能使用bitmap.compress
,因为我的位图是 null 。也就是说,在您拥有有效的compress
对象之后,就可以使用Bitmap
方法了,
问题:
是否有使用BitmapFactory.Options
的解决方案可以导致与bitmap.compress
相同的结果:较低的quality
,相同的dimensions
?
答案 0 :(得分:1)
是否有使用BitmapFactory.Options的解决方案可以导致与bitmap.compress相同的结果:质量较低,尺寸相同?
不是。 Bitmap
本身就没有压缩。
问题是,由于我的位图为空,因此我无法使用bitmap.compress。
您正在将已编码的JPEG图像与Bitmap
混淆。编码的JPEG图像被压缩。 Bitmap
不是。 Bitmap
总是会根据宽度,高度和每个像素的位数来消耗内存。
每个像素可以使用不同数量的位。 BitmapFactory
使用ARGB_8888
(32位/像素)。如果您的图像没有Alpha通道,并且可以使用缩小的颜色范围,则可以切换到RGB_565
(16位/像素)。
否则,您唯一的选择是减小图像的大小(宽度和高度)。
答案 1 :(得分:0)
您无法根据需要压缩位图。
您可能已经知道这一点-但是,是的!您可以通过此方法找到合适的inSampleSize,以根据尺寸保持质量。
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
此方法选自Android Loading Large images efficiently。
您可以了解有关处理Bimap here
的更多信息