2011-01-28 65 views
20

感谢Schermvlieger询问this问题上anddev.org速度优化使用BitmapFactory.Options.inSampleSize的

我只是复制他的问题,从而没有人对对方回答网站,我也面临同样的问题。

我想知道什么是BitmapFactory.Options.inSampleSize关于显示图像的速度的最佳使用。
说明文档中提到使用是2的功率值,所以我用2,4,8,16等

我想知道的事情是工作:

  1. 我应该重新取样下来到仍然大于屏幕分辨率的最小尺寸,或者我应该采样到足够大的尺寸以避免OutOfMemoryError
  2. 如何计算可以在内存不足的情况下仍可以显示的图像的最大尺寸?图像的颜色深度是否也起作用以及显示的深度?
  3. 通过两种机制显示图像是否高效(大文件为BitmapFactory,小文件为setImageURI())顺便说一句,我使用的是ImageSwitcher
  4. 它会帮助在应用程序的开始时创建Bitmap,BitmapFactory.OptionsinTempStorage,或者在需要时创建它们吗?

回答

11

您应该总是尝试加载和预先缩放图像,以使它们尽可能接近其最终显示的大小。在绘图时缩放图像非常昂贵,应该不惜一切代价避免。

考虑到图像的内存成本,是的,颜色deptch起着非常重要的作用。 ALPHA_8格式的图像使用每像素1字节,RGB_565或ARGB_4444中的图像使用每像素2字节,而ARGB_8888中的图像使用每像素4字节。显示的深度根本不重要。你应该总是尝试使用ARGB_8888以获得最佳质量,但如果图像不透明,565可以足够好。

+0

当你说“在绘制时缩放图像非常昂贵”,它是否包含options.inSampleSize? – kape123 2013-02-14 03:44:57

+0

inSampleSize用于在加载时缩放图像,而不是在绘制时间。这是预分辨图像的一种非常好的方法。 – 2013-02-14 17:51:23

3

在这里你可以调用用户定义的方法shrinkmehtod,实际上发送字符串文件的路径和高度和宽度,以减少图像的方法。

Bitmap bit=shrinkmethod(arrpath1[position], 100, 100); 


      //iv.setImageURI(Uri.parse(arrpath1[position])); 
      iv.setImageBitmap(bit); 

这是用户定义的方法,以编程方式减少图像的大小。

Bitmap shrinkmethod(String file,int width,int height){ 
     BitmapFactory.Options bitopt=new BitmapFactory.Options(); 
     bitopt.inJustDecodeBounds=true; 
     Bitmap bit=BitmapFactory.decodeFile(file, bitopt); 

     int h=(int) Math.ceil(bitopt.outHeight/(float)height); 
     int w=(int) Math.ceil(bitopt.outWidth/(float)width); 

     if(h>1 || w>1){ 
      if(h>w){ 
       bitopt.inSampleSize=h; 

      }else{ 
       bitopt.inSampleSize=w; 
      } 
     } 
     bitopt.inJustDecodeBounds=false; 
     bit=BitmapFactory.decodeFile(file, bitopt); 



     return bit; 

    } 

我希望这会帮助你减小尺寸。

4

您已经提出了很好的问题,但这一切取决于您的需求以及您使用的内存量。 我建议查看这个链接,了解关于位图的许多提示:http://developer.android.com/training/displaying-bitmaps/index.html

总之,您应该考虑缓存,缩减采样,并尽可能使用足够好的位图格式。

这里是我的问题的答案:

  1. 为什么不能两者兼而有之?如果您认为可能存在OOM,请尝试回收旧的未使用的位图,然后再次检查。

  2. 就可以计算出该位图的(估计)大小:

    宽度×高度×bytesPerPixel

    其中bytesPerPixel通常是4或2(取决于位图格式)。

  3. 从来没有使用setImageURI,所以我不能帮你。我建议在后台线程中下载图像(使用asyncTask是一种方法),并在准备就绪时显示它们。

  4. 如果只有少数你知道不会占用很多内存,我想没关系。我仍然认为缓存可能会更好。