【问题标题】:Out of Memory error while loading images. [Android]加载图像时出现内存不足错误。 [安卓]
【发布时间】:2016-01-06 10:52:26
【问题描述】:

我想从图库中挑选图片并在我的应用中用作个人资料图片。到目前为止,我已经尝试过了。

这是我的 InfoGet 课程。 loadImagefromGallery 在点击时被调用。

 public void loadImagefromGallery(View view) {

  /*  Intent galleryIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

    startActivityForResult(galleryIntent, RESULT_LOAD);*/
    Intent gallery_Intent = new Intent(getApplicationContext(), GalleryUtil.class);
    startActivityForResult(gallery_Intent, GALLERY_ACTIVITY_CODE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == GALLERY_ACTIVITY_CODE) {
        if(resultCode == Activity.RESULT_OK){
         String picturePath = data.getStringExtra("picturePath");
            //perform Crop on the Image Selected from Gallery
            performCrop(picturePath);
        }
    }

    if (requestCode == RESULT_CROP ) {
        if(resultCode == Activity.RESULT_OK){
            Bundle extras = data.getExtras();
            Bitmap selectedBitmap = extras.getParcelable("data");
            // Set The Bitmap Data To ImageView
            pro.setImageBitmap(selectedBitmap);
            pro.setScaleType(ImageView.ScaleType.FIT_XY);
        }
    }
}

private void performCrop(String picUri) {
    try {
        //Start Crop Activity

        Intent cropIntent = new Intent("com.android.camera.action.CROP");
        // indicate image type and Uri
        File f = new File(picUri);
        Uri contentUri = Uri.fromFile(f);

        cropIntent.setDataAndType(contentUri, "image/*");
        // set crop properties
        cropIntent.putExtra("crop", "true");
        // indicate aspect of desired crop
        cropIntent.putExtra("aspectX", 1);
        cropIntent.putExtra("aspectY", 1);
        // indicate output X and Y
        cropIntent.putExtra("outputX", 280);
        cropIntent.putExtra("outputY", 280);

        // retrieve data on return
        cropIntent.putExtra("return-data", true);
        // start the activity - we handle returning in onActivityResult
        startActivityForResult(cropIntent, RESULT_CROP);
    }
    // respond to users whose devices do not support the crop action
    catch (ActivityNotFoundException anfe) {
        // display an error message
        String errorMessage = "your device doesn't support the crop action!";
        Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
        toast.show();
    }
}

这是我的 GalleryUtil 代码

public class  GalleryUtil extends Activity {
private final static int RESULT_SELECT_IMAGE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final String TAG = "GalleryUtil";

String mCurrentPhotoPath;
File photoFile = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try{
        //Pick Image From Gallery
        Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, RESULT_SELECT_IMAGE);
    }catch(Exception e){
        e.printStackTrace();
    }
}

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

    switch(requestCode){
        case RESULT_SELECT_IMAGE:

            if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
                try{
                    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();

                    //return Image Path to the Main Activity
                    Intent returnFromGalleryIntent = new Intent();
                    returnFromGalleryIntent.putExtra("picturePath",picturePath);
                    setResult(RESULT_OK,returnFromGalleryIntent);
                    finish();
                }catch(Exception e){
                    e.printStackTrace();
                    Intent returnFromGalleryIntent = new Intent();
                    setResult(RESULT_CANCELED, returnFromGalleryIntent);
                    finish();
                }
            }else{
                Log.i(TAG, "RESULT_CANCELED");
                Intent returnFromGalleryIntent = new Intent();
                setResult(RESULT_CANCELED, returnFromGalleryIntent);
                finish();
            }
            break;
    }
}

}

我需要帮助,任何人都可以对现有代码进行一些更改。我不想从头开始重建任何东西。我想在发布下一个更新之前优化这个图像选择器。现有代码适用于具有大量 RAM(如 1GB 左右)的设备。 请帮我。 并解释你做了什么以及它是如何工作的。非常感谢。

【问题讨论】:

  • 可能重复的问题,检查stackoverflow.com/questions/5697760/… 看看你是否有一个独特的问题,或者它已经在stackoverflow的其他地方讨论过。
  • 我无法在我的代码中实现。帮我做到这一点

标签: android image optimization scale profile


【解决方案1】:

我做了那个方法从路径读取图像并解决了这个问题,也许它可以帮助你:

public static Bitmap readBitmap(Uri selectedImage, int resizeFactor)
    {
        Bitmap bm = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = resizeFactor;
        AssetFileDescriptor fileDescriptor = null;
        try
        {
            fileDescriptor = context.getContentResolver().openAssetFileDescriptor(selectedImage, "r");
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        } finally
        {
            try
            {
                bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
                fileDescriptor.close();
            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        return bm;
    }

属性为Uri selectedImageint resizeFactor

selectedImage 上,您需要从图像中放置一个路径,在resizeFactor 上放置一个整数,通常我使用数字10,尝试使用它或尝试使用另一个(向下/向上)

现在如果你想穿上ImageView,你可以使用它。

ImageView.setImageBitmap(readBitmap(Path, 10));

稍后你需要清除位图内容以避免OutOfMemory,使用那个方法:

public static void clearBitmap(Bitmap bm)
    {
        bm.recycle();
    }

【讨论】:

  • 这行得通吗?在哪里调用 clearBitmap? public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == GALLERY_ACTIVITY_CODE) { if(resultCode == Activity.RESULT_OK){ String picturePath = data.getStringExtra("picturePath"); //对从图库中选择的图像执行裁剪 readBitmap(Uri.parse(picturePath), 10); performCrop(picturePath); } } & theres a error on context in front of fileDescriptor
  • fileDescriptor = Context.getContentResolver().openAssetFileDescriptor(selectedImage, "r"); getContentResolver() 不能从静态上下文中引用。
  • 好的,从我的方法中删除 static 或将您的课程更改为 final class
猜你喜欢
  • 1970-01-01
  • 2014-01-11
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
相关资源
最近更新 更多