Android: BitmapFactory.decodeByteArray - 降低图像质量
Android: BitmapFactory.decodeByteArray - reduce image quality
这是我的用例:
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
异常,但是 bitmap 大小(尺寸:宽度 x高度)减少。
相反,我正在寻找与此类似的内容:
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
在此示例中,位图的 质量 降低了,但其大小 仍然相同。当我在 ImageView
:
中显示它时
iv.setImageBitmap(bitmap);
与原版占space,质量减半
问题是,在我的情况下我不能使用 bitmap.compress
,因为我的位图是 null。也就是说,compress
方法可以在 之后使用 你有一个有效的 Bitmap
对象,这不是我的情况。
问题:
是否有任何使用 BitmapFactory.Options
的解决方案可以导致与 bitmap.compress
相同的结果:较低的 quality
,相同的 dimensions
?
Is there any solution using BitmapFactory.Options which can lead to the same result as bitmap.compress: lower quality, same dimensions?
不是真的。 Bitmap
本质上是未压缩的。
The problem is, that in my case I cannot use bitmap.compress because my bitmap is null.
您将编码的 JPEG 图像与 Bitmap
混淆了。编码的 JPEG 图像被压缩。 Bitmap
不是。 Bitmap
总是 根据宽度、高度和每个像素的位数消耗内存。
您可以使用不同的每像素位数。 BitmapFactory
使用 ARGB_8888
(32 bits/pixel)。如果您的图像没有 Alpha 通道并且您可以接受缩小的颜色范围,您可以切换到 RGB_565
(16 bits/pixel)。
否则,您唯一的选择就是缩小图像的尺寸(宽度和高度)。
您不能随意压缩位图。
您可能已经知道了 - 但是,是的!你可以通过这个方法找到合适的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
这是我的用例:
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
异常,但是 bitmap 大小(尺寸:宽度 x高度)减少。
相反,我正在寻找与此类似的内容:
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
在此示例中,位图的 质量 降低了,但其大小 仍然相同。当我在 ImageView
:
iv.setImageBitmap(bitmap);
与原版占space,质量减半
问题是,在我的情况下我不能使用 bitmap.compress
,因为我的位图是 null。也就是说,compress
方法可以在 之后使用 你有一个有效的 Bitmap
对象,这不是我的情况。
问题:
是否有任何使用 BitmapFactory.Options
的解决方案可以导致与 bitmap.compress
相同的结果:较低的 quality
,相同的 dimensions
?
Is there any solution using BitmapFactory.Options which can lead to the same result as bitmap.compress: lower quality, same dimensions?
不是真的。 Bitmap
本质上是未压缩的。
The problem is, that in my case I cannot use bitmap.compress because my bitmap is null.
您将编码的 JPEG 图像与 Bitmap
混淆了。编码的 JPEG 图像被压缩。 Bitmap
不是。 Bitmap
总是 根据宽度、高度和每个像素的位数消耗内存。
您可以使用不同的每像素位数。 BitmapFactory
使用 ARGB_8888
(32 bits/pixel)。如果您的图像没有 Alpha 通道并且您可以接受缩小的颜色范围,您可以切换到 RGB_565
(16 bits/pixel)。
否则,您唯一的选择就是缩小图像的尺寸(宽度和高度)。
您不能随意压缩位图。
您可能已经知道了 - 但是,是的!你可以通过这个方法找到合适的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