Android:BitmapFactory.decodeByteArray-降低图像质量

时间:2019-06-20 13:58:30

标签: java android bitmap jvm out-of-memory

这是我的用例:

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

2 个答案:

答案 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

的更多信息