android - 图像压缩期间出现内存不足错误

标签 android bitmap compression out-of-memory

我目前正在学习来自 this site 的教程压缩我的图像。它在某些手机上运行良好,例如 LG G3、Moto G 和一些三星机型。但是,它会导致某些手机(例如 Xiomi Mi4)在该行出现 Out-of-Memory 错误。

options.inTempStorage = new byte[16 * 1024];

整个代码如下-

public Bitmap compressImage(String imageLocation) {
    Bitmap scaledBitmap = null;

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap bmp = BitmapFactory.decodeFile(imageLocation, options);

    int actualHeight = options.outHeight;
    int actualWidth = options.outWidth;
    float maxHeight = 700.0f;//816.0f;
    float maxWidth = 500.0f; //612.0f;
    float imgRatio = actualWidth / actualHeight;
    float maxRatio = maxWidth / maxHeight;

    if (actualHeight > maxHeight || actualWidth > maxWidth) {
        if (imgRatio < maxRatio) {
            imgRatio = maxHeight / actualHeight;
            actualWidth = (int) (imgRatio * actualWidth);
            actualHeight = (int) maxHeight;
        } else if (imgRatio > maxRatio) {
            imgRatio = maxWidth / actualWidth;
            actualHeight = (int) (imgRatio * actualHeight);
            actualWidth = (int) maxWidth;
        } else {
            actualHeight = (int) maxHeight;
            actualWidth = (int) maxWidth;
        }
    }
    //options.inSampleSize = utils.calculateInSampleSize(options, actualWidth, actualHeight);
    options.inJustDecodeBounds = false;
    options.inDither = false;
    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inTempStorage = new byte[16 * 1024];
    try {
        bmp = BitmapFactory.decodeFile(imageLocation, options);
    } catch (OutOfMemoryError exception) {
        exception.printStackTrace();
    }
    try {
        scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
    } catch (OutOfMemoryError exception) {
        exception.printStackTrace();
    }

    float ratioX = actualWidth / (float) options.outWidth;
    float ratioY = actualHeight / (float) options.outHeight;
    float middleX = actualWidth / 2.0f;
    float middleY = actualHeight / 2.0f;

    Matrix scaleMatrix = new Matrix();
    scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

    Canvas canvas = new Canvas(scaledBitmap);
    canvas.setMatrix(scaleMatrix);
    canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));


    ExifInterface exif;
    try {
        exif = new ExifInterface(imageLocation);

        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
        Log.d("EXIF", "Exif: " + orientation);
        Matrix matrix = new Matrix();
        if (orientation == 6) {
            matrix.postRotate(90);
            Log.d("EXIF", "Exif: " + orientation);
        } else if (orientation == 3) {
            matrix.postRotate(180);
            Log.d("EXIF", "Exif: " + orientation);
        } else if (orientation == 8) {
            matrix.postRotate(270);
            Log.d("EXIF", "Exif: " + orientation);
        }
        scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
    } catch (IOException e) {
        e.printStackTrace();
    }

    return scaledBitmap;
}

有人可以帮我解决问题/就如何改进此代码以减少内存占用提出建议。

最佳答案

You are dealing with large bitmaps and loading all of them at run time. You have to deal very carefully with large bitmaps by loading the size that you need not the whole bitmap at once and then do scaling.

请检查下面的链接

  1. Is it possible to catch out of memory exception in java?

关于android - 图像压缩期间出现内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33412024/

相关文章:

php - 在 PostgresQL 上保存之前压缩字符串是否有值(value)?

Android 布局边距不适用

java - JSONArray 空内容 Java 和 Android

android - RecordingProxy::releaseRecordingFrame 在 Android 手机上录制时每 25 毫秒在日志中重复一次

android - java.lang.RuntimeException : Canvas: trying to use a recycled bitmap, 无法追踪确切位置

c# - 从生成的位图图像创建视频 C#

安卓:bitmapfactory.decodestream 返回 null

google-apps-script - 如何压缩谷歌驱动器中的文件?

c# - 你应该压缩 html 页面吗?如果是这样,如何在 .net 中做到这一点?

android - 适用于 Android/iOS/WinPhone 的 Xamarin 共性层