在Galaxy note 1(基于AOSP的ROM)上的Android中的OutOfMemoryError尝试将分辨率提高一点点

时间:2014-12-07 12:27:57

标签: android bitmap android-camera resolution

我一直处理Android上的图片,已经有好几天了,我似乎无法解决它。

在我的应用中有一个"添加照片"按钮。当用户点击它时,她可以从图库中选择一张照片,或者用相机拍摄一张新照片。

但是为了避免出现OutOfMemoryError,我必须降低分辨率,以至于发送到服务器的图片几乎只是一个缩略图。

当我将200更改为250时,在此行上

会出现上述错误! 位图缩放= Bitmap.createScaledBitmap(bitmap2,200,200,true);

(错误发生在Android 4.2+上,而不是在较低的Androids上。它在Android 4.1上完全正常,即使有400,400)

我的代码中哪一部分错了?

以下是代码:

 public class CreatePropertyActivity5 extends ActionBarActivity {
protected static final int SELECT_PICTURE = 1;
private static final int ACTIVITY_REQUEST_CODE_IMAGE = 100;
private static final int IMAGE_DESCRIPTION = 200;
LinearLayout ll; 
private List<File> cameraImageFiles;
private JSONRequestForCreatePropertyListing propertyListing;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_create_property_5);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    propertyListing = (JSONRequestForCreatePropertyListing) getIntent().getSerializableExtra("JSONRequestForCreatePropertyListing");
    CreatePropertListingAsync cplp = new CreatePropertListingAsync(this, propertyListing);
    cplp.execute();

}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.create_property_activity5, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

public void onClickTakePicture(View v) throws IOException {
    // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);     
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);


    cameraImageFiles = new ArrayList<File>();

    int i=0;
    for(ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.MEDIA_IGNORE_FILENAME, ".nomedia");

        //** below 4 lines put the uri of the camera taken picture to the EXTRA_OUTPUT 
        File cameraImageOutputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "myFileName");
        cameraImageFiles.add(cameraImageOutputFile);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraImageFiles.get(i)));
        i++;

        cameraIntents.add(intent);
    }

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, "add new");

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
    startActivityForResult(chooserIntent, ACTIVITY_REQUEST_CODE_IMAGE);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent)
{
    ll = (LinearLayout) findViewById(R.id.llCreatePropertyImages);

    switch(requestCode) { 

    // For sending photos to server. We come here from activity51
    case IMAGE_DESCRIPTION:
        String s = imageReturnedIntent.getStringExtra("key");
        //user entered description is in "key"
        imageView.setTag(s);
        Bitmap bitmap1 = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
        ByteArrayOutputStream stream=new ByteArrayOutputStream();
        bitmap1.compress(Bitmap.CompressFormat.PNG, 90, stream);
        byte[] image=stream.toByteArray();
        String img_str = Base64.encodeToString(image, 0);

        //This part sends the picture to the server
        ArrayList<Photos> photos = new ArrayList<Photos>();
        photos.add(new Photos(new Ax(img_str)));

        int id = Integer.parseInt((String) ((TextView) findViewById(R.id.txt_property_listing_ID)).getText());
        int editPass = Integer.parseInt((String) ((TextView) findViewById(R.id.txt_property_listing_password)).getText());
        JSONRequestForAddPhoto jr = new JSONRequestForAddPhoto(id, editPass, photos);

        new AddPhotoAsync(this, jr).execute();
        break;

    //For choosing photos from gallery or taking one with camera
    case ACTIVITY_REQUEST_CODE_IMAGE:
        if(resultCode == RESULT_OK){

            Uri uri = null;
            if(imageReturnedIntent == null){   //since we used EXTRA_OUTPUT for camera, so it will be null

                for(int i=0;i<cameraImageFiles.size();i++){
                    if(cameraImageFiles.get(i).exists()){
                        uri = Uri.fromFile(cameraImageFiles.get(i));
                        break;
                    }
                }
            }
            else {  // from gallery
                uri = imageReturnedIntent.getData();
            }

            if(uri != null){
                imageView = new ImageView(this);
                imageView.setPadding(0, 10, 0, 0);
                ll.setVisibility(View.VISIBLE);
                try {

                    Bitmap bitmap2 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
                    Bitmap scaled = Bitmap.createScaledBitmap(bitmap2, 250, 250, true);
                    bitmap2.recycle();
                    imageView.setImageBitmap(scaled);
                    ll.addView(imageView);

                    //*** show activity51
                    Intent i= new Intent(this, CreatePropertyActivity51.class);
                    i.putExtra("photo", scaled);


                    startActivityForResult(i,IMAGE_DESCRIPTION);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我认为您的代码没有错,但可以进行优化。但如果你处理一些大图像,我建议你看一下这个答案:https://stackoverflow.com/a/27270469/2101822

答案 1 :(得分:0)

我查看了您的代码,但您没有采用开发人员网站中提到的方式 如何load large bitmaps efficiently

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

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

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

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

先试试吧!