最佳使用BitmapFactory.Options.inSampleSize来提高速度

时间:2011-01-28 05:39:08

标签: android bitmap bitmapfactory

感谢 Schermvlieger anddev.org 上询问this问题,

我只是将他的问题复制到SO,因为没有人在其他网站上回复,我也面临同样的问题。

我想知道BitmapFactory.Options.inSampleSize在显示图像的速度方面的最佳用途是什么 文档提到使用2的幂的值,所以我正在使用2,4,8,16等。

我想知道的是:

  1. 我应该重新采样到仍然大于屏幕分辨率的最小尺寸,还是应该采样到足以避免OutOfMemoryError的尺寸?
  2. 如何在不耗尽内存的情况下计算仍然可以显示的图像的最大尺寸?图像的颜色深度是否也起作用,显示的深度是什么?
  3. 通过两种机制显示图像是否有效(BitmapFactory用于大文件,setImageURI()用于较小文件。顺便说一下,我使用的是ImageSwitcher
  4. 是否有助于在应用程序开头创建BitmapBitmapFactory.OptionsinTempStorage,或者只在需要时动态创建它们?

4 个答案:

答案 0 :(得分:11)

您应该始终尝试加载和预缩放图像,使其尽可能接近最终显示的尺寸。在绘图时缩放图像非常昂贵,应该不惜一切代价避免。

考虑到图像的内存成本,是的,颜色 - deptch起着非常重要的作用。 ALPHA_8格式的图像每像素使用1个字节,RGB_565或ARGB_4444中的图像每像素使用2个字节,ARGB_8888中的图像使用每个像素4个字节。显示器的深度根本不重要。您应该始终尝试使用ARGB_8888来获得最佳质量,但如果您的图像不透明,那么565就足够了。

答案 1 :(得分:4)

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

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

以下是我对问题的回答:

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

  2. 您可以计算位图的(估计)大小:

    width * height * bytesPerPixel

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

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

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

答案 2 :(得分: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;

    }

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

答案 3 :(得分:0)

您好,尝试使用此逻辑计算inSampleSize

private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
    val (height: Int, width: Int) = options.run { outHeight to outWidth }
    var inSampleSize = 1

    if (height > reqHeight || width > reqWidth) {
        val halfHeight: Int = height / 2
        val halfWidth: Int = 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
}