且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

高分辨率图像 - OutOfMemoryError

更新时间:2022-06-05 09:10:57

应该对您有帮助的三个提示:

Three hints which should help you:

  1. 使用它来加载您的图像,来自 Loading Large BitmapsAndroid 文档:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

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

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

  • 确保内存中只有一个 Bitmap 实例.显示后,调用 recycle() 并将您的引用设置为 null.您可以使用 内存分配跟踪器 查看分配的内容.您还可以按照评论中的建议阅读 HPROF 文件.

  • Make sure you have only one instance of your Bitmap in memory. After displaying it, call recycle() and set your reference to null. You can use Memory Allocation Tracker to see what is allocated. You can also read HPROF files, as suggested in comments.

    默认使用 ARGB_8888 像素格式,这意味着每像素 4 个字节.非常好的文章:位图质量、条带和抖动.您的图像是 JPEG,因此它没有透明度,因此您在 alpha 通道的每个像素上浪费了 1 个字节.这不太可能,但也许在可接受的质量下,您可以使用更经济的格式.看看.例如,也许 RGB_565.像素需要 2 个字节,因此您的图像会轻 50%.您可以启用抖动以提高 RGB_565 的质量.

    By default ARGB_8888 pixel format is used, which means 4 bytes per pixel. Very good article: Bitmap quality, banding and dithering. Your image is JPEG, so it doesn't have transparency, so you are wasting 1 byte on every pixel for alpha channel. It's not very probable, but maybe with acceptable quality you can use even more economical format. Take a look at them. Maybe RGB_565 for example. It takes 2 bytes for pixel, so your image would be 50% lighter. You can enable dithering to improve the quality of RGB_565.