BitmapFactory.decodeFile上的OutofMemory

时间:2015-06-29 10:06:15

标签: android out-of-memory bitmapfactory

在我的应用程序中,我必须将所选图像上传到parse.com以进行打印输出。 我必须保持图像质量,我无法调整图像大小。 我必须在parse.com上传图片..我不需要在设备屏幕上显示它们(图像是表格图库或来自facebook专辑......或来自SD卡)。我不能按照要求缩小它们。

我在BitmapFactory.decodeFile()上遇到OutOfMemory错误。如何解决这个错误?

正在使用android:largeHeap =" true"可以解决我的问题吗?

我在三星SM-G900T上遇到了这次崩溃,但不是在模拟器上......

我试图把

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

但它不起作用。 下面是我的AsyncTask类,用于将图像上传到Parse.com

class UploadFileFromURL extends AsyncTask<String, String, String> {
    ProgressDialog dialog;
    String albumId = "";

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }


    @Override
    protected String doInBackground(String... f_url) {

        try {
            for (int i = 0; i < arrListImgBean.size(); i++) {

                if (!isUploading || objAsyncUpload.isCancelled()) {
                    break;
                }
                try {
                    if (arrListImgBean.get(i).imageStatus == 1)
                        continue;
                    else if (arrListImgBean.get(i).imageStatus == 2) {
                        isPhotodeleted = true;
                        publishProgress("" + countUploaded);
                        deletePhoto(i);

                    }

                    else {
                        isPhotodeleted = false;
                        try {

                            Bitmap b = null;
                            InputStream is = null;
                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inJustDecodeBounds = false;
                            options.inPreferredConfig = Config.RGB_565; // to
                                                                        // reduce
                                                                        // the
                                                                        // memory
                            options.inDither = true;
                            if (arrListImgBean.get(i).imgURL
                                    .startsWith("http")) {
                                try {
                                    URL url = new URL(
                                            arrListImgBean.get(i).imgURL);
                                    is = url.openConnection()
                                            .getInputStream();
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                b = BitmapFactory.decodeStream(is, null,
                                        options);

                            } else {
                                b = BitmapFactory.decodeFile(
                                        arrListImgBean.get(i).imgURL,
                                        options);
                            }

                            // Convert it to byte
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            // Bitmap out = Bitmap.createScaledBitmap(b,
                            // 1500, 2100, false);
                            b.compress(Bitmap.CompressFormat.PNG, 100,
                                    stream);
                            byte[] image = stream.toByteArray();
                            ParseFile file = new ParseFile("Android.png",
                                    image);
                            file.save();
                            String uploadedUrl = file.getUrl();
                            if (uploadedUrl != null) {

                                ParseObject imgupload = new ParseObject(
                                        "Photo");
                                imgupload.put("userName", ParseUser
                                        .getCurrentUser().getEmail());
                                imgupload.put("photoURL", file);
                                imgupload.put("photoID",
                                        arrListImgBean.get(i).imageId);
                                imgupload.put("count", 1);
                                imgupload.put("albumName", albumId);
                                imgupload.save();
                                String objId = imgupload.getObjectId();

                                if (objId != null && !objId.isEmpty()) {
                                    countUploaded++;
                                    publishProgress("" + countUploaded);

                                    database.updateImageStatus(
                                            arrListImgBean.get(i).imageId,
                                            Constants.STATUS_UPLOADED,
                                            objId, uploadedUrl);
                                }

                            }

                        } catch (Exception e) {

                        }

                    }
                } catch (Exception e) {
                    isUploading = false;
                    e.printStackTrace();
                }

            }
        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }
        return null;

    }



    @Override
    protected void onPostExecute(String file_url) {
        // dismissDialog(progress_bar_type);
        isUploading = false;
        btnUploadImages.setBackgroundResource(R.drawable.upload_photo);
        vprogress.setCompoundDrawables(null, null, null, null);
        // stopLoading();
        setProgressMsg();

    }

}

3 个答案:

答案 0 :(得分:0)

android:largeHeap="true"

这行代码可以解决您的问题,但它是一个临时解决方案,但如果图像数量或图像大小增加,可能会再次发生崩溃。最好使用Picasso库来处理图像

答案 1 :(得分:0)

考虑你有一个1024x1024dp的图像和一个512x512dp的设备(这两个图只是为了理解)。因此,在这种情况下,在较小规模的设备上加载全分辨率图像会浪费内存。您可以做的是缩小图像,使其适合设备屏幕。通过这种方式,您不仅可以节省大量内存,还可以获得清晰,清晰的图像。

我正在添加用于缩放我目前在项目中使用的图像的代码。

final FileInputStream streamIn = new FileInputStream(file);
final BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inJustDecodeBounds = true;
//  Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 300;
int width_tmp = ops.outWidth, height_tmp = ops.outHeight;
int scale = 1;
while (true) {
      if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
             break;
            }
      width_tmp /= 2;
      height_tmp /= 2;
      scale *= 2;
 }

 ops.inJustDecodeBounds = false;
 ops.inSampleSize = scale;
 bitmap = BitmapFactory.decodeStream(streamIn, null, ops); //This gets the image
 streamIn.close();

根据设备的屏幕显示大小选择REQUIRED_SIZE值。

答案 2 :(得分:0)

        try {
            image = readInFile(path);
        }
        catch(Exception e) { 
            e.printStackTrace();
        }

        // Create the ParseFile
        ParseFile file = new ParseFile("picturePath", image);
        // Upload the image into Parse Cloud
        file.saveInBackground();

        // Create a New Class called "ImageUpload" in Parse
        ParseObject imgupload = new ParseObject("Image");

        // Create a column named "ImageName" and set the string
        imgupload.put("Image", "picturePath");


        // Create a column named "ImageFile" and insert the image
        imgupload.put("ImageFile", file);

        // Create the class and the columns
        imgupload.saveInBackground();

        // Show a simple toast message
        Toast.makeText(LoadImg.this, "Image Saved, Upload another one ",Toast.LENGTH_SHORT).show();


 private byte[] readInFile(String path) throws IOException {
     // TODO Auto-generated method stub
     byte[] data = null;
     File file = new File(path);
     InputStream input_stream = new BufferedInputStream(new FileInputStream(
        file));
     ByteArrayOutputStream buffer = new ByteArrayOutputStream();
     data = new byte[16384]; // 16K
     int bytes_read;
     while ((bytes_read = input_stream.read(data, 0, data.length)) != -1) {
         buffer.write(data, 0, bytes_read);
     }
     input_stream.close();
     return buffer.toByteArray();

 }