Optimal use of BitmapFactory.Options.inSampleSize for speed

前端 未结 4 1533
野的像风
野的像风 2021-02-05 05:15

Thanks to Schermvlieger for asking this question on anddev.org,

I\'m just copying his question to SO as nobody replied on th

相关标签:
4条回答
  • 2021-02-05 05:47

    You should always try to load and pre-scale images so that they are as close as possible to their final displayed size. Scaling images at drawing time is extremely expensive and should be avoided at all cost.

    Considering the memory cost of an image, yes, the color-deptch plays a very important role. Images in ALPHA_8 format use 1 byte per pixel, images in RGB_565 or ARGB_4444 use 2 bytes per pixel and images in ARGB_8888 use 4 bytes per pixel. The depth of the display does not matter at all. You should always try to use ARGB_8888 to get the best possible quality, but 565 can be good enough if your image is opaque.

    0 讨论(0)
  • 2021-02-05 05:59

    Here you can call the user defined method shrinkmehtod that actually send the string file path and the height and width to be reduce image to method.

     Bitmap bit=shrinkmethod(arrpath1[position], 100, 100);
    
    
                //iv.setImageURI(Uri.parse(arrpath1[position]));
                iv.setImageBitmap(bit);
    

    This is user defined method to reduce the size of image programmatically.

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

    I hope this will help you to reduce size.

    0 讨论(0)
  • 2021-02-05 06:01

    Hi try out calculating the inSampleSize using this logic

    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
    }
    
    0 讨论(0)
  • 2021-02-05 06:06

    You've asked good questions , but it all depends on your needs and how much memory you use. I recommend checking out this link for many tips regarding bitmaps: http://developer.android.com/training/displaying-bitmaps/index.html .

    In short , you should consider caching , downsampling , and using a good-enough bitmap format whenever you can.

    Here's my answers to your questions:

    1. Why not both? if you think there might be OOM , try to recycle old,unused bitmaps and then check again .

    2. you can calculate the (estimated) size of the bitmap :

      width*height*bytesPerPixel

      where bytesPerPixel is usually 4 or 2 (depending on the bitmap format) .

    3. Never used setImageURI , so I can't help you with that. I suggest downloading images in a background thread (using asyncTask is one way to do so) and showing them when it's ready.

    4. If there are only a few that you know that won't take a lot of the memory , i guess it's ok. I still think caching could be better.

    0 讨论(0)
提交回复
热议问题