显示大图片上来看寻呼机从SD卡中的机器人 [英] Showing large images on view pager from sdcard in android

查看:137
本文介绍了显示大图片上来看寻呼机从SD卡中的机器人的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,我有非常高的分辨率为80〜150的图像,我必须向他们展示在视图中的寻呼机。我写了解码的简单机制,但在第二页后得到OutOfMemory错误。我试过很多,但无法找到确切的解决方案,以避免这种情况。我个人的建议是,如果我们能在装载部分的图像的图片浏览,那么也许我们避免这一点,但我不知道如何来实现这一目标。请建议对此的任何解决方案。

I have a problem that I have 80 to 150 images of very High Resolution and I have to show them in a view pager. I had written the simple mechanism of decoding but get OutofMemory Error after the 2nd Page. I tried very much but unable to find the exact solution to avoid that. My own suggestion is that if we will able to load a image in parts on an Image View then perhaps we avoid this but I don't know how to achieve this. Please suggest any solution regarding this.

code:

private class MyPagerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return Integer.parseInt(pagesCount);
        }


        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0==((ImageView)arg1);
        }
        @Override
        public void destroyItem(View container, int position, Object object) {
             View view = (View)object;
                ((ViewPager) container).removeView(view);
                view = null;
        }
        @Override
        public View instantiateItem(View container, final int position) {
            final ImageView imgPage = new ImageView(getApplicationContext());
            /*imgPage.setImageURI(Uri.withAppendedPath(
                    Uri.parse(Environment.getExternalStorageDirectory()+"/MAGZ/"+magName+issueName), "" + (issueName+position)+".png"));*/
            //imgPage.setImageBitmap(BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/MAGZ/"+magName+issueName+"/"+(issueName+position)));
            //destroyItem(container, position, imgPage);
            imgPage.setScaleType(android.widget.ImageView.ScaleType.FIT_XY);
            imgPage.setImageDrawable(getImageFromSdCard(issueName+position));
            //imgPage.setImageResource(getImageFromSdCard(issueName+position));


            ((ViewPager) container).addView(imgPage,0); 
            return imgPage;
        }
    }


    public Drawable getImageFromSdCard(String imageName) {
        Drawable d = null;
        try {
            String path = Environment.getExternalStorageDirectory()+"/MAGZ/"+magName+"/"+magName+issueName;
            bitmap = BitmapFactory.decodeFile(path + "/" + imageName
                    + ".png");

           // d = new BitmapDrawable(bitmap);
            d = new BitmapDrawable(decodeFile(new File(path+"/"+imageName+".png")));
           // bitmap.recycle();
            bitmap = null;
        } catch (IllegalArgumentException e) {
            bitmap = null;
        }
        return d;

    }


    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){
        try {
            //Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);

            //The new size we want to scale to
            final int REQUIRED_SIZE=550;

            //Find the correct scale value. It should be the power of 2.
            int scale=1;
            while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
                scale*=2;

            //Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    }

在此先感谢。

Thanks in advance.

推荐答案

inJustDe codeBounds和放大器; inSampleSize

您在每个PagerAdapter调用解码高清晰度的图像,如果你愿意通过2的幂,减少去codeD位存储器(X / 2,X / 4 ... X:原始位大小) ,然后再为这个方法

You are decoding high resolution images at each PagerAdapter call, and if you are willing to reduce the decoded bitmap memory by powers of 2 (x/2, x/4 ... x : original bitmap size), then go for this method

Bitmap.recycle()

一个非常方便的方法,在正确的地方使用时,可以创造奇迹。我假设你正在设置BitmapDrawable或致电setImageBitmap到ImageView的。添加下面的代码片段<一href="http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#destroyItem%28android.view.ViewGroup,%20int,%20java.lang.Object%29"相对=nofollow> destroyItem() PagerAdapter的回调。

A very handy method, when used at the right place, can work wonders. I am assuming that you are setting a BitmapDrawable or calling setImageBitmap to an ImageView. Add the following snippet in destroyItem() callback of PagerAdapter.

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    View view = (View) object;
    ImageView imageView = (ImageView) view.findViewById(R.id.image_view);
    Drawable drawable = imageView.getDrawable();
    if(drawable instanceof BitmapDrawable) {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        if(bitmapDrawable != null) {
            Bitmap bitmap = bitmapDrawable.getBitmap();
            if(bitmap != null && !bitmap.isRecycled()) bitmap.recycle();    
        }
    }
    ((ViewPager) container).removeView(view);
}

我们的想法是,当所有子视图从寻呼机删除,它的位图应该得到回收,这样你就不会依赖于GC呼吁清除内存给你。

The idea is that when any child view is removed from Pager, its bitmap should get recycled, that way you would not depend on GC calls to clear memory for you.

largeHeap = TRUE

添加此属性的Manifest.xml &lt;应用&GT; 标记。无论是支持largeHeap,它会增加堆内存的一些较大的值,甚至去到8倍。

Add this property in Manifest.xml <application> tag. Wherever largeHeap is supported, it will increase heap memory to some large value, even goes till 8 times.

此外,通常不持有任何愚蠢引用任何位图,C他们只是去$ C $和分配给它查看,其余的将被照顾。

Also, in general don't hold any silly references to any bitmap, just decode them and assign it to View, rest will be taken care of.

希望有所帮助。 :)

这篇关于显示大图片上来看寻呼机从SD卡中的机器人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆