当我从Gallery中选择图像时OutOfMemory

时间:2014-10-30 11:42:35

标签: android bitmap out-of-memory

我尝试从图库中获取图像,但是当我尝试加载大图像时,我会在一段时间后收到以下错误:

10-30 13:36:55.180  16246-16246/ua.khuta.freeturnforadmin E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: ua.khuta.freeturnforadmin, PID: 16246
java.lang.OutOfMemoryError
        at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
        at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
        at java.lang.StringBuilder.append(StringBuilder.java:216)
        at ua.khuta.freeturnforadmin.activities.NewsDetailActivity.onActivityResult(NewsDetailActivity.java:265)

我的代码:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    switch (requestCode) {
        case SELECT_PHOTO:
            if (resultCode == RESULT_OK) {
                Uri selectedImage = imageReturnedIntent.getData();
                InputStream imageStream = null;
                try {
                    imageStream = getContentResolver().openInputStream(selectedImage);
                    yourSelectedImage = BitmapFactory.decodeStream(imageStream);
                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                    yourSelectedImage.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
                    byte[] byteArray = byteArrayOutputStream.toByteArray();
                    String image = Base64.encodeToString(byteArray, Base64.DEFAULT);
                    imagesToShow.add(new News.Image("", image + "base64"));
                    changedImages.add(new News.Image("fid_new", image));
                    adapter.notifyDataSetChanged();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
    }
}

我看过this tutorial on d.android.com,但它没有帮助我。

EDITED: 我已经添加了您的方法并尝试下一个代码,但之后我又有了另一个例外

    public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
        super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
        switch (requestCode) {
            case SELECT_PHOTO:
                if (resultCode == RESULT_OK) {
                    Uri selectedImage = imageReturnedIntent.getData();
                        yourSelectedImage = decodeImage(selectedImage.getPath());
                        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                        yourSelectedImage.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
                        byte[] byteArray = byteArrayOutputStream.toByteArray();
                        String image = Base64.encodeToString(byteArray, Base64.DEFAULT);
                        imagesToShow.add(new News.Image("", image + "base64"));
                        changedImages.add(new News.Image("fid_new", image));
                        adapter.notifyDataSetChanged();
                }
        }
    }

现在我得到了:

     Process: ua.khuta.freeturnforadmin, PID: 24895
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent { dat=content://media/external/images/media/33642 flg=0x1 }} to activity {ua.khuta.freeturnforadmin/ua.khuta.freeturnforadmin.activities.NewsDetailActivity}: java.lang.NullPointerException
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3351)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3394)
            at android.app.ActivityThread.access$1300(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at ua.khuta.freeturnforadmin.activities.NewsDetailActivity.onActivityResult(NewsDetailActivity.java:257)
            at android.app.Activity.dispatchActivityResult(Activity.java:5423)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3347)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3394)
            at android.app.ActivityThread.access$1300(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

行指针处的空指针:

 yourSelectedImage.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);

2 个答案:

答案 0 :(得分:1)

当您从图库中提取图像时,请使用此功能。

private void decodeImage(final String path) {
    int targetW = iv.getWidth();
    int targetH = iv.getHeight();

    final BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    int scaleFactor = Math.min(photoW / targetW, photoH / targetH);

    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;
    Bitmap bitmap = BitmapFactory.decodeFile(path, bmOptions);
    imageView.setImageBitmap(bitmap);
   }

现在当你获得imagepath后,使用这个函数,如

   decodeImage(yourimagePath);

EDIT:

从Gallery获取图像然后在onActivityResult()方法中使用此代码。

 Uri selectedImage = data.getData();
 String[] filePath = { MediaStore.Images.Media.DATA };
 Cursor c = getContentResolver().query(selectedImage, filePath,
                    null, null, null);
 c.moveToFirst();
 int columnIndex = c.getColumnIndex(filePath[0]);
 yourSelectedImage = c.getString(columnIndex);
 c.close();
 if (yourSelectedImage!= null) {
    Log.v("Image", yourSelectedImage);          
    decodeImage(yourSelectedImage);

 }

答案 1 :(得分:0)

您可以设置largeHeap =" true"在你的清单中。除此之外,还有各种其他技术来处理位图,您可以找到here。有一个名为毕加索的图书馆,可以帮助你很多。只是不要通过skipMemoryCache()缓存图像。我想这会对你有很多帮助:)