Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 图像压缩期间内存不足错误_Android_Bitmap_Compression_Out Of Memory - Fatal编程技术网

Android 图像压缩期间内存不足错误

Android 图像压缩期间内存不足错误,android,bitmap,compression,out-of-memory,Android,Bitmap,Compression,Out Of Memory,我目前正在按照教程从压缩我的图像。它在LG G3、Moto G和一些三星型号的手机上运行良好。但是,它会导致某些手机(如Xiomi Mi4)在这条线路上出现内存不足错误 options.inTempStorage = new byte[16 * 1024]; 整个代码如下所示- public Bitmap compressImage(String imageLocation) { Bitmap scaledBitmap = null; BitmapFactory.Option

我目前正在按照教程从压缩我的图像。它在LG G3、Moto G和一些三星型号的手机上运行良好。但是,它会导致某些手机(如Xiomi Mi4)在这条线路上出现内存不足错误

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;
}
公共位图压缩图像(字符串图像位置){
位图缩放位图=空;
BitmapFactory.Options=new-BitmapFactory.Options();
options.inJustDecodeBounds=true;
位图bmp=BitmapFactory.decodeFile(图像位置,选项);
int实际高度=options.outHeight;
int actualWidth=options.outWidth;
浮点最大高度=700.0f;//816.0f;
浮点最大宽度=500.0f;//612.0f;
浮动高度=实际宽度/实际高度;
浮点最大比值=最大宽度/最大高度;
如果(实际高度>最大高度| |实际宽度>最大宽度){
if(imgRatiomaxRatio){
imgRatio=最大宽度/实际宽度;
实际高度=(int)(imgRatio*实际高度);
实际宽度=(int)最大宽度;
}否则{
实际高度=(int)最大高度;
实际宽度=(int)最大宽度;
}
}
//options.inSampleSize=utils.calculateInSampleSize(选项、实际宽度、实际高度);
options.inJustDecodeBounds=false;
options.inDither=false;
options.inpurgable=true;
options.inInputShareable=true;
options.inTempStorage=新字节[16*1024];
试一试{
bmp=BitmapFactory.decodeFile(图像位置,选项);
}捕获(OutOfMemoryError异常){
异常。printStackTrace();
}
试一试{
scaledbimat=Bitmap.createBitmap(实际宽度、实际高度、Bitmap.Config.ARGB_8888);
}捕获(OutOfMemoryError异常){
异常。printStackTrace();
}
浮动比率=实际宽度/(浮动)选项。向外宽度;
浮动比率=实际高度/(浮动)选项。超出高度;
浮动中间点x=实际宽度/2.0f;
浮动中间Y=实际高度/2.0f;
矩阵scaleMatrix=新矩阵();
scaleMatrix.setScale(ratioX、ratioY、middleX、middleY);
画布画布=新画布(缩放位图);
canvas.setMatrix(scaleMatrix);
drawBitmap(bmp,middleX-bmp.getWidth()/2,middleY-bmp.getHeight()/2,新绘制(Paint.FILTER_位图_标志));
出口接口;
试一试{
exif=新的ExifInterface(图像位置);
int-orientation=exif.getAttributeInt(ExifInterface.TAG_-orientation,0);
Log.d(“EXIF”,“EXIF:+方向”);
矩阵=新矩阵();
如果(方向==6){
矩阵旋转后(90);
Log.d(“EXIF”,“EXIF:+方向”);
}否则如果(方向==3){
矩阵旋转后(180);
Log.d(“EXIF”,“EXIF:+方向”);
}否则如果(方向==8){
矩阵旋转后(270);
Log.d(“EXIF”,“EXIF:+方向”);
}
scaledBitmap=Bitmap.createBitmap(scaledBitmap,0,0,scaledBitmap.getWidth(),scaledBitmap.getHeight(),矩阵,true);
}捕获(IOE异常){
e、 printStackTrace();
}
返回缩放位图;
}
有没有人能帮我一下/给我一些建议,如何改进这段代码,从而减少内存占用

您正在处理大型位图,并在运行时加载所有位图 时间您必须非常小心地通过加载来处理大型位图 您不需要一次将整个位图的大小 缩放

请查看下面的链接


  • 您应该根据所需的大小设置样本大小。试着设置 options.inSampleSize动态调整。i、 e

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

    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) {
    
                final int halfHeight = height / 2;
                final int halfWidth = width / 2;
    
                // Calculate the largest inSampleSize value that is a power of 2 and
                // keeps both
                // height and width larger than the requested height and width.
                while ((halfHeight / inSampleSize) > reqHeight
                        && (halfWidth / inSampleSize) > reqWidth) {
                    inSampleSize *= 2;
                }
            }
    
            return inSampleSize;
        }
    

    我在那个活动中只加载了一个位图。@VarunAgarwal好的。减小图像大小此代码用于减小图像大小。我用相机拍摄了一张图像(2-4mb,取决于相机),并将其缩小到700kb左右。但它对小米m4和其他一些设备不起作用。如果我使用异步任务,那会有什么不同吗?@VarunAgarwal您可以尝试
    异步任务
    。但主要的问题是尺寸太大。我想这就是为什么问题是真的,但现在xiomi的图片就是那个尺寸。因此,我必须处理和压缩它们,因为如果我按原样上载图像,它将花费太长时间,而且根本没有效率。您可以降低质量尝试设置选项。inSampleSize=16