简体   繁体   English

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

[英]Android: BitmapFactory.decodeByteArray - reduce image quality

This is my use case: 这是我的用例:

ByteArray ba; // Some value is assigned here
Bitmap bitmap = BitmapFactory.decodeByteArray(ba, 0, ba.length);

Because the ByteArray object is to large, an OutOfMemoryError exception is thrown at the second line, when doing: 由于ByteArray对象太大,因此在执行以下操作时,第二行将引发OutOfMemoryError异常:

BitmapFactory.decodeByteArray(ba, 0, ba.length);

Already tried: 已经尝试过:

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);

The problem with this solution is that, using inSampleSize attribute, it avoids the OutOfMemoryError exception, but the bitmap size (dimensions: width x height) is reduced. 该解决方案的问题在于,使用inSampleSize属性,它避免了OutOfMemoryError异常,但是位图大小(尺寸:宽度x高度)减小了。

Instead I'm looking for something similar to this: 相反,我正在寻找类似的东西:

bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);

At this example the quality of the bitmap is reduced, BUT its size is still the same. 在此示例中,位图的质量降低了, 但其大小仍然相同。 When I display it in an ImageView : 当我在ImageView显示它时:

iv.setImageBitmap(bitmap);

It occupies the same space as the original, but with half quality. 它占用的空间与原始空间相同,但质量却降低了一半。

The problem is, that in my case I cannot use bitmap.compress because my bitmap is null . 问题是,就我而言,我不能使用bitmap.compress因为我的位图为null That is, the compress method can be used after you have a valid Bitmap object, which is not my case. 也就是说, 您拥有有效的Bitmap对象之后 ,才可以使用compress方法,但事实并非如此。

Question: 题:

Is there any solution using BitmapFactory.Options which can lead to the same result as bitmap.compress : lower quality , same dimensions ? 是否有使用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? 是否有使用BitmapFactory.Options的解决方案可以导致与bitmap.compress相同的结果:质量较低,尺寸相同?

Not really. 并不是的。 A Bitmap is uncompressed by its very nature. Bitmap由于其本质而未被压缩。

The problem is, that in my case I cannot use bitmap.compress because my bitmap is null. 问题是,在我的情况下,我不能使用bitmap.compress,因为我的位图为null。

You are confusing an encoded JPEG image with a Bitmap . 您正在将编码的JPEG图像与Bitmap混淆。 An encoded JPEG image is compressed. 编码的JPEG图像被压缩。 A Bitmap is not. Bitmap不是。 A Bitmap always consumes memory based on the width, height, and the number of bits per pixel. Bitmap 总是根据宽度,高度和每个像素的位数消耗内存。

You could use a different number of bits per pixel. 您可以为每个像素使用不同数量的位。 BitmapFactory uses ARGB_8888 (32 bits/pixel). BitmapFactory使用ARGB_8888 (32位/像素)。 You could switch to RGB_565 (16 bits/pixel), if your image has no alpha channel and you can live with the reduced range of colors. 如果您的图像没有Alpha通道,并且可以使用缩小的颜色范围,则可以切换到RGB_565 (16位/像素)。

Otherwise, your only option is to reduce the size (width and height) of the image. 否则,您唯一的选择是减小图像的大小(宽度和高度)。

You cannot compress the bitmap as you want. 您不能根据需要压缩位图。

You may already know this - But, Yes! 您可能已经知道这一点-但是,是的! you can find the appropriate inSampleSize by this method to maintain the quality based on the size. 您可以通过此方法找到合适的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;
}

This method is picked from Android Loading Large images efficiently . 该方法是从Android中有效选择的

You can read more about handing Bimaps here 您可以在此处阅读有关处理Bimap的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM