Kjframeforandroid Framework Learning----efficient loading of bitmap

Source: Internet
Author: User

Kjframeforandroid Framework Project Address: https://github.com/kymjs/KJFrameForAndroid

When we write the Android program, we will definitely use a lot of pictures. Then the compression of the image is naturally necessary. Why compress? I don't think it's important to stress that everyone will know this one when they first learn Android: We write applications that have a maximum memory limit, where Java programs and C programs (when the NDK calls) share this memory size, An oom (OutOfMemory) exception can occur when the program takes up too much memory. As to what this maximum memory is, we can verify it by calling the Runtime.getruntime (). MaxMemory () method.

is due to memory size limitations This is the key reason (in fact, I think a 1M picture and a 10k picture, loading speed must be different it). If your control is only 40*40 pixels in size, just to show a thumbnail, it's not worth it to load a picture of a 1024x768 pixel completely into memory, so we'll compress the image. The

Bitmapfactory class provides multiple methods (Decodebytearray, DecodeFile, Decoderesource, and so on) for creating bitmap objects, and we can choose the appropriate method based on the source of the image. However, these methods allocate memory for bitmap that have already been read, which can cause oom to appear if it is a very large picture. For this Each parsing method provides a bitmapfactory.options parameter, which allows the parsing method to suppress the allocation of memory for bitmap by setting the Injustdecodebounds property of the parameter to true, but the return value of the bitmapfactory after this setting is also is no longer a bitmap object, but is null. Although bitmap is null, Bitmapfactory.options's outwidth, Outheight, and Outmimetype properties are assigned values. Using this technique allows us to get the image's long and wide values and types before loading the image, thus compressing the image as appropriate.

Bitmapfactory.options Options = new Bitmapfactory.options ();      Options.injustdecodebounds = true;    Bitmapfactory.decodefile (pathName, Options);      int h = options.outheight;      int w = options.outwidth; String type = Options.outmimetype;

Then know the picture of the width of the high, how to compress it? Bitmapfactory.options has a insamplesize attribute, which indicates that the original width height of the picture becomes 1/insamplesize times, if the original is 1024*768,insamplesize= 2, then the picture becomes 512*384 after compression.
Finally set bitmapfactory.options the appropriate insamplesize value, and remember to set the Injustdecodebounds back to false, and then call Bitmapfactory the corresponding method of creating bitmap, and the options passed in, You can get the compressed picture.

Here is a snippet of code from the open source Android application Development Framework Kjframeforandroid

 /**     *  image compression processing (using options)      *       * @ How to use   first you have to set the options Injustdecodebounds property to true,bitmapfactory.decode one picture at a time.      *        then pass the options along with the desired width and height to this method.      *        Then use the return value of this method to make a parameter call Bitmapfactory.decode create the picture.      *      *  @explain   Bitmapfactory Create bitmap will attempt to allocate memory for the bitmap already built      *       &NBSP;&NBSP;&NBSP;&NBSP, it is easy to cause oom to appear. For this purpose, an optional options parameter is provided for each method of creation      *         &NBSP;&NBSP, set the Injustdecodebounds property of this parameter to true to prevent the parsing method from allocating memory for bitmap      *   &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP, the return value is no longer a bitmap object,  but null. Although bitmap is null, the options outwidth,      *           Both the Outheight and Outmimetype properties are assigned values.      *  @param  reqWidth     *              Target width      *  @param   reqheight     *              Target Height      */    public static  Bitmapfactory.options calculateinsamplesize (             final bitmapfactory.options options, int reqwidth, int reqheight)  {        //  height and width of the source image          final int height = options.outHeight;         final int width = options.outwidth;        int insamplesize = 1;         if  (height > reqheight | |  width > reqwidth)  {             //  calculates the ratio between the actual width and the target width             final  int heightratio = math.round (float)  height                     /  (float)   Reqheight);            final int  Widthratio = math.round (float)  width /  (float)  reqwidth);             //  selection width and high school minimum ratio as the value of insamplesize, which ensures the width and height of the final image              //  must be greater than or equal to the width and height of the target.             insamplesize = heightratio  < widthRatio ? heightRatio : widthRatio;         }        //  Set Compression scale          options.inSampleSize = inSampleSize;         options.injustdecodebounds = false;        return  options;    }

The above method is suitable for use when reading a picture from an unknown source, because you do not know the size of this unknown source image, then there is another way is to use the image loaded in memory, the memory has been loaded to compress the image to be stored back to the local, So you can turn a 1M-sized image into a 10K picture.
The core idea of this method is to first turn the picture into an output stream, and record the byte array size of the output stream, by calling the Compress method of the bitmap object, compressing and formatting the picture once, and the size of the byte array to the target size of the desired compression, the compression ratio is obtained, and call the bitmap scaling method, scaling the computed compression ratio, thus obtaining the compressed method.
Let's continue to look at another piece of code in the Kjframeforandroid framework:

/**     *  Image compression method: (using Compress method)      *       *  @explain   Do not process if the size of the bitmap itself is less than maxsize      *  @param  bitmap     *              pictures to compress      *  @param  maxsize     *              size after compression, unit kb      */    public static void imagezoom (Bitmap bitmap, double  maxsize)  {        //  put bitmap into the array, Intended to obtain the size of the bitmap (larger than the actual file read)         bytearrayoutputstream baos  = new bytearrayoutputstream ();        //  format, quality, Output stream         bitMap.compress (Bitmap.compressformat.jpeg, 100, baos);         Byte[] b = baos.tobytearray ();        //  convert bytes to kb         double mid = b.length / 1024;         //  get bitmap size   How many times the maximum size is allowed          double i = mid / maxSize;         //  determine if the bitmap space is greater than the maximum allowable space   if it is greater then compression   less than compression          if  (i > 1)  {            //   Zoom picture   Use square root here   to compress the width and height of the square root twice              //  (keep the width and height unchanged, the size of the maximum occupied space after zooming)              bitmap =&nbsP;scale (Bitmap, bitmap.getwidth ()  / math.sqrt (i),                     bitmap.getheight ()  /  MATH.SQRT (i));        }    }/***      *  How to zoom images      *      *  @param  src     *            &NBSP: Source Picture resources      *  @param  newWidth     *  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP: Scaled width      * @ param newheight     *             : Height after scaling      */    public static bitmap  scale (Bitmap src,&nbsP;double newwidth, double newheight)  {        //   Record the width and height of src         float width = src.getwidth ();         float height = src.getheight ();         //  Create a Matrix container         matrix  matrix = new matrix ();        //  Calculating the zoom ratio         float scaleWidth =  ((float)  newwidth)  / width;        float scaleHeight =  ((float)  newheight)  / height;        //  Start zoom          matrix.postscale (scalewidth, scaleheight);         //  Create a shrinkPut the picture         return bitmap.createbitmap (Src, 0, 0,   (int)  width,  (int)  height,                 matrix, true);     }



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.