【问题标题】:Compress bitmap or byte[] after taking picture拍照后压缩位图或字节[]
【发布时间】:2015-11-28 11:12:55
【问题描述】:

我正在尝试在拍照后减小位图的大小。我可以将大小减小到最大 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[] 吗? 我只想发送黑白文件。

【问题讨论】:

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


    【解决方案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。这种格式也有“阿尔法通道”。但它并不完美:一些浏览器与它不兼容。所以你必须在你的项目中小心这一点。

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

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

    注意事项

    1) 如果这个级别的压缩还不够,你可以使用压缩的质量(你可以在 bmp.compress() 方法中看到的'100')。请注意 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)。

    【讨论】:

    • 关于第三个注释,我不确定将图像转换为灰度会减小其大小。我前段时间对此进行了测试,对我来说输出文件的大小是相同的。
    • 图片转灰度后用什么方法压缩?
    【解决方案2】:

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

    【讨论】:

    • 我可以设置其他选项来使其成为灰度吗?
    • 要将您的图像转换为灰度,您可以查看此处:stackoverflow.com/questions/8381514/… 但这不会减少您的文件大小。
    猜你喜欢
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    相关资源
    最近更新 更多