在Android中将位图压缩为特定的字节大小

时间:2018-08-19 16:57:55

标签: java android kotlin android-bitmap bitmapfactory

有没有一种方法可以将位图压缩为特定的字节大小?例如1.5MB。问题是到目前为止,我所看到的所有示例都是调整宽度和高度的大小,但是我的要求是调整字节大小。那可能吗? 另外,压缩位图的最直接,最正确的方法是什么?我对这个话题不是很熟悉,并且希望从一开始就走正确的方向。

4 个答案:

答案 0 :(得分:1)

您可以很容易地计算出位图的大小 width * height * bytes per pixel = size

bytes per pixel由您的颜色模型定义的地方,说RGBA_F16是8个字节,而ARGB_8888是4个字节,依此类推。有了这个,您应该能够弄清楚您想要图像的宽度,高度和颜色编码。

有关位值,请参见https://developer.android.com/reference/android/graphics/Bitmap.Config

有关位图内存管理的更多信息,请参见https://developer.android.com/topic/performance/graphics/manage-memory

答案 1 :(得分:1)

这是我创建的帮助程序类。这会同时按宽度/高度和最大文件大小压缩位图。将图像缩小到1.5mb并不是一门确切的科学,但是它的作用是,如果图像大于要求的大小,它将使用jpeg压缩位图并将质量降低80%。一旦文件大小小于要求的大小,它将以字节数组的形式返回位图。

public static byte[] getCompressedBitmapData(Bitmap bitmap, int maxFileSize, int maxDimensions) {
    Bitmap resizedBitmap;
    if (bitmap.getWidth() > maxDimensions || bitmap.getHeight() > maxDimensions) {
        resizedBitmap = getResizedBitmap(bitmap,
                                         maxDimensions);
    } else {
        resizedBitmap = bitmap;
    }

    byte[] bitmapData = getByteArray(resizedBitmap);

    while (bitmapData.length > maxFileSize) {
        bitmapData = getByteArray(resizedBitmap);
    }
    return bitmapData;
}

public static Bitmap getResizedBitmap(Bitmap image, int maxSize) {
    int width = image.getWidth();
    int height = image.getHeight();

    float bitmapRatio = (float) width / (float) height;
    if (bitmapRatio > 1) {
        width = maxSize;
        height = (int) (width / bitmapRatio);
    } else {
        height = maxSize;
        width = (int) (height * bitmapRatio);
    }
    return Bitmap.createScaledBitmap(image,
                                     width,
                                     height,
                                     true);
}

private static byte[] getByteArray(Bitmap bitmap) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    bitmap.compress(Bitmap.CompressFormat.JPEG,
                    80,
                    bos);

    return bos.toByteArray();
}

答案 2 :(得分:1)

这对我有用。 将原始位图的区域缩放到50%,并压缩位图,直到其大小<200k

A-B

答案 3 :(得分:0)

在以下位置查看我的答案(不使用while循环): How to reduce image size into 1MB

如果您当前通过的位图处于ARGB_8888配置中(因此,每个像素4个字节。如果不是ARGB_8888,则可以使用以下方法将其转换为该位图):此方法有效

/**
 * Convert a Bitmap to a Bitmap that has 4 bytes per pixel
 * @param input The bitmap to convert to a 4 bytes per pixel Bitmap
 * 
 * @return The converted Bitmap. Note: The caller of this method is 
 * responsible for reycling the input
 */
public static Bitmap to4BytesPerPixelBitmap(@NonNull final Bitmap input){
    final Bitmap bitmap = Bitmap.createBitmap(input.width, input.height, Bitmap.Config.ARGB_8888);
    // Instantiate the canvas to draw on:
    final Canvas canvas = new Canvas(bitmap);
    canvas.drawBitmap(input, 0, 0, null);
    // Return the new bitmap:
    return bitmap;  
}