拍照后压缩bitmap或byte[]

Compress bitmap or byte[] after taking picture

我想在拍照后缩小位图的大小。我能够将大小减小到最大 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);

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

如果不需要 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);

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

有3种方法可以压缩你的图片(你从相机收到的“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 channel' 在某些情况下可能是必需的。

与之前的代码相比只有一个变化:

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

3) WebP 格式 -> 这是迄今为止最好的格式。 PNG 格式的 1.0 MB 图像在 JPG 格式中可以压缩到 100-200KB,而在 WebP 中只能压缩到 30-50 KB。这种格式也有 'alpha channel'。但它并不完美:一些浏览器与它不兼容。所以你在项目中一定要注意这一点。

与之前的代码相比只有一个变化:

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 [=56= 中的演讲] 2016 (link).