BitmapFactory.de codeFILE出与图片2400x2400记忆 [英] BitmapFactory.decodeFile out of memory with images 2400x2400

查看:129
本文介绍了BitmapFactory.de codeFILE出与图片2400x2400记忆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从文件发送图像到服务器。服务器在2400x2400的分辨率请求图像。

我试图做的是:

1),使用BitmapFactory.de codeFILE使用正确的inSampleSize获取一个位图。

2)的COM preSS的JPEG图像与40%的质量

3)恩code以base64图像

4)发送到服务器

我无法实现的第一步,它抛出一个内存溢出异常。我敢肯定,inSampleSize是正确的,但我想即使有inSampleSize位图是巨大(DDMS中约30 MB)。

任何想法如何能做到这一点?我可以做这些步骤没有创建位图对象?我的意思是这样做的文件系统,而不是RAM内存。

这是当前code:

  //下面的函数计算正确的inSampleSize
位图图像= Util.de codeSampledBitmapFromFile(的ImagePath,宽,高);
// COM pressing图像
ByteArrayOutputStream BAOS =新ByteArrayOutputStream();
image.com preSS(Bitmap.Com pressFormat.JPEG,40,BAOS);
// EN code图像
字符串连接codeDIMAGE = Base64.en codeToString(baos.toByteArray(),Base64.DEFAULT));
公共静态INT calculateInSampleSize(BitmapFactory.Options选项,诠释reqWidth,诠释reqHeight){
    //原始高度和图像宽度
    最终诠释身高= options.outHeight;
    最终诠释宽度= options.outWidth;
    INT inSampleSize = 1;    如果(高度> reqHeight ||宽度GT; reqWidth){        //计算的高度和宽度的比率要求的高度和宽度
        最终诠释heightRatio = Math.round((浮点)高度/(浮点)reqHeight);
        最终诠释widthRatio = Math.round((浮点)宽/(浮点)reqWidth);        //选择最小比率inSampleSize值,这将保证
        //使用两个维度大于或等于所述最终图像
        //请求的高度和宽度。
        inSampleSize = heightRatio< widthRatio? heightRatio:widthRatio;
    }    返回inSampleSize;
}公共静态位图德codeSampledBitmapFromFile(字符串路径,INT reqWidth,诠释reqHeight){    //首先去code。与inJustDe codeBounds = true来检查尺寸
    最后BitmapFactory.Options选项=新BitmapFactory.Options();
    options.inJustDe codeBounds = TRUE;
    BitmapFactory.de codeFILE(路径选择);    //计算inSampleSize
    options.inSampleSize = calculateInSampleSize(选项,reqWidth,reqHeight);    //德code位与inSampleSize集
    options.inJustDe codeBounds = FALSE;
    返回BitmapFactory.de codeFILE(路径选择);
}


解决方案

您可以跳过ARGB_8888,并使用RGB_565代替,然后再抖动图像preserve质量好

  BitmapFactory.Options选项=新BitmapFactory.Options();
 options.inJustDe codeBounds = FALSE;
 options.in preferredConfig = Config.RGB_565;
 options.inDither = TRUE;

I need to send an image from a file to a server. The server request the image in a resolution of 2400x2400.

What I'm trying to do is:

1) Get a Bitmap using BitmapFactory.decodeFile using the correct inSampleSize.

2) Compress the image in JPEG with a quality of 40%

3) Encode the image in base64

4) Sent to the server

I cannot achieve the first step, it throws an out of memory exception. I'm sure the inSampleSize is correct but I suppose even with inSampleSize the Bitmap is huge (around 30 MB in DDMS).

Any ideas how can do it? Can I do these steps without created a bitmap object? I mean doing it on filesystem instead of RAM memory.

This is the current code:

// The following function calculate the correct inSampleSize
Bitmap image = Util.decodeSampledBitmapFromFile(imagePath, width,height);   
// compressing the image
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 40, baos);
// encode image
String encodedImage = Base64.encodeToString(baos.toByteArray(),Base64.DEFAULT));


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;
}

public static Bitmap decodeSampledBitmapFromFile(String path,int reqWidth, int reqHeight) {

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

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

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(path,options);
}

解决方案

you can skip ARGB_8888, and use RGB_565 instead, and then dither then images to preserve good quality

 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inJustDecodeBounds = false;
 options.inPreferredConfig = Config.RGB_565;
 options.inDither = true;

这篇关于BitmapFactory.de codeFILE出与图片2400x2400记忆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆