将 JPG 图像压缩到以 KB 为单位的给定大小?

路易斯

我在输入中有一个由相机返回的字节数组。

我需要缩小我的图像以使其大小等于 500KB。我正在尝试使用位图来实现这一点,但我找不到如何获得正确的compression值。

public static byte[] compressCapture(byte[] capture) {

    // How to get the right compression value ?
    int compression = 50;

    Bitmap bitmap  = BitmapFactory.decodeByteArray(capture, 0, capture.length);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, compression, outputStream);
    return outputStream.toByteArray();
}

问题是压缩与图像大小不成正比,这意味着compression等于 50 不会将图像大小除以 2。

有没有办法在不依赖于焦点或智能手机型号的输出中获得固定的图像尺寸?

编辑 :

我不想使用文件(我使用机密数据)。

路易斯

更新 01/16/2018

最简单的方法是使用BitmapFactory.Options.inSampleSize解码字节数组并同时压缩它。这是文档

 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inSampleSize = 4; // If you want an image four times smaller than the original
 Bitmap decoded = BitmapFactory.decodeByteArray(data, 0, data.length, options);

旧答案,请不要使用这个

由于显然无法一次性实现这一目标,因此我实施了一个迭代过程以达到以 KB 为单位的给定大小。

我从等于 80 的压缩系数开始,如果还不够,我会降低这个系数,然后重试,直到大小低于我的阈值。

static COMPRESSION_PERCENTAGE_START = 80;
static IMAGE_COMPRESSION_EXPECTED_MAX_ITERATIONS = 3;
static IMAGE_COMPRESSION_STEP_PERCENT = 5;

// For logging
static IMAGE_COMPRESSION_EXPECTED_MAX_ITERATIONS = 5;

static byte[] compressCapture(byte[] capture, int maxSizeKB) {
    long maxSizeByte = ((long) maxSizeKB) * 1_000;

    if (capture.length <= maxSizeByte) return capture;

    byte[] compressed = capture;

    // Chosen arbitrarily so that we can compress multiple times to reach the expected size.
    int compression = COMPRESSION_PERCENTAGE_START;

    Bitmap bitmap = BitmapFactory.decodeByteArray(capture, 0, capture.length);
    ByteArrayOutputStream outputStream;
    int iterations = 0;
    while (compressed.length > maxSizeByte) {
        // Just a counter
        iterations++;

        compression -= IMAGE_COMPRESSION_STEP_PERCENT;

        outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, compression, outputStream);
        compressed = outputStream.toByteArray();
    }

    if (iterations > IMAGE_COMPRESSION_EXPECTED_MAX_ITERATIONS) {
        Timber.w("Compression process has iterated more than expected, with " + iterations + " iterations.");
    }

    return compressed;
}

这是原始大小1_871_058字节的输出大小

  • 迭代 #1(压缩等于 80):528_593字节
  • 迭代 #2(压缩等于 75):456_591字节

它为我完成了这项工作,但如果您使用它请小心,它当然需要一些微调,我只是在给定的智能手机型号上对其进行了测试。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何获取以kb为单位的位图大小

将具有给定C头的深层嵌套结构解压缩到字典中?

将相机中的图像文件压缩到特定大小

获取以mb或kb为单位的文件大小

以编程方式将面板的图像设置为资源中没有的jpg文件?

将图像转换为jpg Angular 4

将图像从Heic转换为Jpeg / Jpg

为什么将图像导出为jpg时无法获得完全相同的颜色

使用Python将TIF图像覆盖为jpg时出错

使用Imagemagick convert将zip中的所有图像都修复为(KB)

MySQL-将数据库中的图像名称从.jpg更新为.png

将.swf文件压缩到40kb以下

将图像显示为src =“ data:image / jpg; base64,...?

如何获取即将到来的文件大小,以KB为单位

将所有非JPG图像转换为JPG

将许多文件解压缩到给定目录

将许多文件解压缩到给定目录

为什么将普通的jar文件压缩到76%,但在ProGuard缩小并混淆后;它被压缩为102%?!怎么修?

将大图像压缩为小格式

将JPG图像转换为PDF而不用使用ghostscript或itext调整图像大小

将图像从base64解码为jpg

将FabricJS画布导出为带有图像的PNG / JPG

我想在保存之前将捕获的图像调整为最大50 KB -60 KB的大小吗?如何做呢?

将图像上传并存储到服务器时为0 kb

将 vtkChartXY/vtkPlot 导出为高分辨率光栅图像(JPG 或 PNG)

如何在上传和缩放时减小图像的大小(以 KB 为单位)?

边缘将 .jpg 图像显示为随机彩色方块

将图像大小压缩到 1.5 MB,同时发送到多部分 ios swift

是否有任何与 react native 和 expo 一起使用的库可以将图像压缩到目标文件大小?