重新编码图像时出现内存不足异常。

3

我正在尝试将一张图片编码为64位,

在从库中选择图片并尝试保存时,我遇到了以下错误:

内存溢出异常

请问有什么方法可以在不出现内存错误的情况下将该图片转换为64位编码?

        MotorImage.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            Intent i = new Intent(
                    Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

            startActivityForResult(i, RESULT_LOAD_IMAGE);
        }
    });
}


 @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
    Uri selectedImage = data.getData();
    String[] filePathColumn = { MediaStore.Images.Media.DATA };

    Cursor cursor = getContentResolver().query(selectedImage,
            filePathColumn, null, null, null);
    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    String picturePath = cursor.getString(columnIndex);
    cursor.close();


 //   
   ImageView imageView = (ImageView) findViewById(R.id.imageView1);
    imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));



    String imageString = null;

    try {
        Bitmap bm = BitmapFactory.decodeFile(picturePath);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object  
        bm.recycle();
        byte[] b = baos.toByteArray();
        imageString = Base64.encodeToString(b, Base64.DEFAULT);
    } catch (Exception e) {
        e.printStackTrace();
    }




    Toast.makeText(getApplicationContext(), imageString, Toast.LENGTH_SHORT).show();

不要写入到 ByteArrayOutputStream,而是写入到文件、网络套接字等,因为你无法将任意大的数据写入内存。同时也不要编码成 String,因为那也会写入内存。有相应的输出流来处理这些问题。 - zapl
我想将它保存为字符串,因为我将把它存储在SQL Server数据库中,我应该使用什么? - user3245658
你不需要一个 String,你也可以将它流式传输到你的服务器上。具体如何取决于你的服务器和许多其他因素。 - zapl
将图像转换为base64格式并不是一个好主意,应该避免使用。 - njzk2
@njzk2 你有其他的想法吗? - user3245658
1
在文件上使用Base64OutputStream。 - njzk2
3个回答

2

我猜您需要将图片进行缩放和重采样,以适应设备上的限制。尝试像这样做:

// decodes image and scales it to reduce memory consumption
private Bitmap decodeImage(String picturePath) {
    try {
        File file = new File(picturePath);
        // Get image size
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(file), null, opts);

        // The new size we want to scale to
        final int MIN_SIZE = 70;

        // Find the correct scale value.
        int scale = 1;
        while (((opts.outWidth / scale) >> 1) >= MIN_SIZE
                && ((opts.outHeight / scale) >> 1) >= MIN_SIZE) {
            scale <<= 1;
        }

        BitmapFactory.Options opts2 = new BitmapFactory.Options();
        opts2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new FileInputStream(file), null, opts2);
    } catch (FileNotFoundException e) {
    }
    return null;
}

你能否编辑这个程序,使用图像路径的字符串而不是文件? - user3245658
@user3245658 抱歉,我错过了。应该是 opts。已编辑。 - Elliott Frisch
@user3245658 我知道。但是首先你必须解码并缩放它,然后再编码! :) - Elliott Frisch
那么我应该在你的方法之后使用我的原始帖子吗? - user3245658
@user3245658 在你缩放图像后,原来的方法应该可以工作;我建议你尝试一种流式解决方案(而不是内存中的解决方案)来保存;但这应该足以减小输出文件的大小,使其能够正常工作。 - Elliott Frisch

0
尝试在AndroidManifest的应用程序标签内使用android:largeHeap="true",然后您的应用程序将有更多可用的RAM,并且不会抛出oom异常。

你的安卓版本是什么? - Giacomoni

0

如果你阅读过Android的官方文档,你就会知道这是Android上一个常见的问题,建议的解决方案是根据你的需要调整图片的大小。你也可以参考developer.android。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接