【问题标题】:java.lang.OutOfMemoryError while display the images in galleryjava.lang.OutOfMemoryError 在画廊中显示图像时
【发布时间】:2013-12-17 14:11:53
【问题描述】:

当我从 sd 卡加载图像时出现异常

java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)

这是我的代码:

    public class Images extends Activity implements OnItemLongClickListener {
        private Uri[] mUrls;
        String[] mFiles = null;
        ImageView selectImage;
        Gallery g;
        static final String MEDIA_PATH = new String("/mnt/sdcard/DCIM/Camera/");

        @Override
        public void onCreate(Bundle icicle) {

            super.onCreate(icicle);
            setContentView(R.layout.main);
            selectImage = (ImageView) findViewById(R.id.image);
            g = (Gallery) findViewById(R.id.gallery);
            File images = new File(MEDIA_PATH);
            Log.i("files", images.getAbsolutePath());

            File[] imagelist = images.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return ((name.endsWith(".jpg")) || (name.endsWith(".png")));
                }
            });
            Log.i("files", imagelist.toString());
            String[] mFiles = null;
            mFiles = new String[imagelist.length];

            for (int i = 0; i < imagelist.length; i++) {
                mFiles[i] = imagelist[i].getAbsolutePath();
            }
            System.out.println(mFiles.length);

            mUrls = new Uri[mFiles.length];
            System.out.println(mUrls.length);
            for (int i = 0; i < mFiles.length; i++) {
                mUrls[i] = Uri.parse(mFiles[i]);
            }

            g.setAdapter(new ImageAdapter(this));


    //      g.setOnItemSelectedListener(this);
            g.setOnItemLongClickListener(this);



        }

        public class ImageAdapter extends BaseAdapter {

            // int mGalleryItemBackground;

            public ImageAdapter(Context c) {
                mContext = c;
            }

            public int getCount() {
                return mUrls.length;
            }

            public Object getItem(int position) {
                return position;
            }

            public long getItemId(int position) {
                return position;
            }

            public View getView(int position, View convertView, ViewGroup parent) {
                Log.i("ok5", "ok");
                ImageView i = new ImageView(mContext);

                i.setImageURI(mUrls[position]);
                Log.i("ok", "ok");
                i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
                i.setLayoutParams(new Gallery.LayoutParams(100, 100));
                return i;
            }

            private Context mContext;
        }

        @Override
        public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub

            selectImage.setImageURI(mUrls[arg2]);
            System.out.println("path: "+mUrls[arg2]);

            Uri f = mUrls[arg2];
            File f1 = new File(f.toString());
            System.out.println("f1: "+f1);
            return false;
        }

【问题讨论】:

  • 使用 BitmapFactory.Options 解码您的图像路径
  • 我的回答有帮助吗..??

标签: android android-gallery


【解决方案1】:

在加载大型位图文件时,BitmapFactory 类提供了几种解码方法(decodeByteArray()、decodeFile()、decodeResource() 等)。

第 1 步

在解码时将 inJustDecodeBounds 属性设置为 true 可避免内存分配,为位图对象返回 null,但设置 outWidth、outHeight 和 outMimeType。此技术允许您在构建位图(和内存分配)之前读取图像数据的尺寸和类型。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it.

第 2 步

要告诉解码器对图像进行二次采样,将较小的版本加载到内存中,请在 BitmapFactory.Options 对象中将 inSampleSize 设置为 true。

例如,分辨率为 2048x1536 的图像使用 inSampleSize 为 4 进行解码会生成大约 512x384 的位图。将其加载到内存中使用 0.75MB 而不是 12MB 的完整图像。

这是一种根据目标宽度和高度计算样本大小值的方法,该值是 2 的幂:

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);
}

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

    final int halfHeight = height / 2;
    final int halfWidth = width / 2;

    // Calculate the largest inSampleSize value that is a power of 2 and keeps both
    // height and width larger than the requested height and width.
    while ((halfHeight / inSampleSize) > reqHeight
            && (halfWidth / inSampleSize) > reqWidth) {
        inSampleSize *= 2;
    }
}

return inSampleSize;
}

请阅读此链接了解详情。 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

【讨论】:

    猜你喜欢
    • 2019-09-13
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 2016-10-16
    相关资源
    最近更新 更多