拍照后压缩位图或字节[]

时间:2015-09-02 19:39:16

标签: android compression png android-camera android-bitmap

我想在拍照后减小位图的大小。我能够将大小减小到最大900kb,但我想尽可能地减少它

首先我这样做:

public static Bitmap decodeSampledBitmapFromResource(byte[] data,
                                                     int reqWidth, int reqHeight) {
 //reqWidth is 320
//reqHeight is 480
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeByteArray(data, 0, data.length, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeByteArray(data, 0, data.length, options);
}

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    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;

        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

然后这个

bitmap.compress(Bitmap.CompressFormat.PNG, 10, fos);

如何进一步压缩位图?要么 我应该压缩字节[]吗? 我只想发送黑白文件。

2 个答案:

答案 0 :(得分:1)

如果不需要alpha通道,则应使用jpg而不是png。 您还可以更改输出位图的颜色配置:

// Decode bitmap with inSampleSize set
options.inPreferredConfig= Bitmap.Config.RGB_565;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(data, 0, data.length, options);

答案 1 :(得分:1)

我知道这个问题有一些时间,但我认为这个答案可以帮助别人。

压缩图片有三种方法(" byte []数据"您已从相机中收到):

1) PNG 格式 - >当图像有很多不同的颜色时,这是最糟糕的选择,一般来说,拍照时就是这种情况。 PNG格式在标识和类似的图像中更有用。

代码:

String filename = "" //THE PATH WHERE YOU WANT TO PUT YOUR IMAGE
File pictureFile = new File(filename);

try{ //"data" is your "byte[] data" 
    FileOutputStream fos = new FileOutputStream(pictureFile);
    Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
    bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); //100-best quality
    fos.write(data);
    fos.close();
} catch (Exception e){
    Log.d("Error", "Image "+filename+" not saved: " + e.getMessage());
}

2) JPG 格式 - >对于具有大量颜色的图像(压缩的算法与PNG非常不同),它是一个更好的选择,但它没有“alpha通道”。在某些情况下可能是必要的。

上一段代码只有一处变化:

bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos); //100-best quality

3) WebP 格式 - >到目前为止,它是最好的格式。 PNG中1.0 MB的映像可以在JPG中压缩到100-200KB,在WebP中只能压缩到30-50 KB。这种格式还有“alpha通道”。但它并不完美:有些浏览器与它不兼容。所以你必须在项目中小心这一点。

上一段代码只有一处变化:

bmp.compress(Bitmap.CompressFormat.WEBP, 100, fos); //100-best quality

备注

1)如果未达到此级别的压缩,您可以使用压缩的质量( bmp.compress()方法)。请注意JPEG的质量,因为在某些情况下质量为80%,您可以轻松地看到图像中的影响。在PNG和WebP格式中,损失百分比影响较小。

2)减小尺寸的另一种方法是调整图像大小。我发现最简单的方法是通过Bitmap.createScaledBitmap方法(more info)创建一个较小的位图。

3)最后一种方法是将图像分为黑白图像。您可以使用此方法执行此操作:

Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
PS 1 - 如果有人想要更深入地了解Android中的图像压缩方法,我推荐Colt McAnlis在Google I / O 2016中的演讲(link)。