In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains the "Android bitmap picture optimization method is what", the article explains the content is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "Android bitmap picture optimization method is what" it!
Background
In Android development, loading too many pictures and too large can easily cause OutOfMemoryError exception, which is our common memory overflow. Because Android imposes a memory limit on a single application, the default memory allocation is only a few megabytes (depending on the system). If the loaded image is in a compression format such as JPG (JPG supports the highest level of compression, but the compression is lossy), expanding in memory will take up a lot of memory space, which will easily lead to memory overflow. It is important to load Bitmap efficiently. Bitmap refers to a picture in Android. The format of a picture is .jpg. Jpg. Webp and other common formats.
How to choose a picture format
One principle: to reduce the size of the picture as much as possible on the premise of ensuring that the picture is not distorted.
The commonly used picture formats in Android are jpg,jpeg and webp.
Png: lossless compressed image format, which supports Alpha channel. Android cut materials often use this format.
Jpeg: lossy compressed image format, does not support transparent background, suitable for large images with rich colors such as photos, but not suitable for logo
Webp: a picture format that provides both lossy compression and lossless compression, derived from the video coding format VP8. From Google's official website, lossless webp is 26% smaller than jpg on average, lossy webp is 25% smaller than jpeg on average, lossless webp supports Alpha channel, lossy webp supports the same under certain conditions, lossy webp supports after Android4.0 (API 14), lossless and transparent support after Android4.3 (API18)
Using webp can effectively reduce the disk space occupied by the picture while maintaining the clarity of the picture.
Picture compression
Image compression can be considered in three aspects:
1. Quality
Quality compression does not change the size of the picture in memory, but only reduces the size of the disk space occupied by the picture, because quality compression does not change the resolution of the picture, and the size of the picture in memory is calculated according to the number of bytes occupied by a pixel of widthheight. The width and height remain the same, and the size occupied in memory will not change naturally. The principle of quality compression is to reduce the disk space occupied by the picture by changing the bit depth and transparency of the picture, so it is not suitable to be used as a thumbnail, but can be used to reduce the disk space occupied by the picture while maintaining the quality of the picture. In addition, because jpg is lossless compression, setting quality is not valid
/ * quality compression * * @ param format image format jpeg,png,webp * @ param quality picture quality, 0-100. the smaller the number, the worse the quality * / public static void compress (Bitmap.CompressFormat format, int quality) {File sdFile = Environment.getExternalStorageDirectory (); File originFile = new File (sdFile, "originImg.jpg"); Bitmap originBitmap = BitmapFactory.decodeFile (originFile.getAbsolutePath ()); ByteArrayOutputStream bos = new ByteArrayOutputStream () OriginBitmap.compress (format, quality, bos); try {FileOutputStream fos = new FileOutputStream (new File (sdFile, "resultImg.jpg")); fos.write (bos.toByteArray ()); fos.flush (); fos.close ();} catch (FileNotFoundException e) {e.printStackTrace ();} catch (IOException e) {e.printStackTrace ();}} 2. sampling rate
Sampling rate compression is to set BitmapFactory.Options.inSampleSize to reduce the resolution of the picture, and then reduce the disk space and memory size occupied by the picture.
Setting inSampleSize will cause the width and height of the compressed image to be 1/inSampleSize, and the overall size will become one square of the inSampleSize of the original image. Of course, there are some points to note:
InSampleSize less than or equal to 1 will be treated as 1.
InSampleSize can only be set to the square of 2, not the square of 2 will eventually be reduced to the nearest square of 2, if set 7 will be compressed by 4, setting 15 will be compressed by 8.
/ * @ param inSampleSize can calculate a reasonable inSampleSize * / public static void compress (int inSampleSize) {File sdFile = Environment.getExternalStorageDirectory (); File originFile = new File (sdFile, "originImg.jpg"); BitmapFactory.Options options = new BitmapFactory.Options (); / / set this parameter to read only the width and height of the image into options, and will not read the whole picture into memory to prevent oom options.inJustDecodeBounds = true Bitmap emptyBitmap = BitmapFactory.decodeFile (originFile.getAbsolutePath (), options); options.inJustDecodeBounds = false; options.inSampleSize = inSampleSize; Bitmap resultBitmap = BitmapFactory.decodeFile (originFile.getAbsolutePath (), options); ByteArrayOutputStream bos = new ByteArrayOutputStream (); resultBitmap.compress (Bitmap.CompressFormat.JPEG, 100, bos); try {FileOutputStream fos = new FileOutputStream (new File (sdFile, "resultImg.jpg")); fos.write (bos.toByteArray ()); fos.flush () Fos.close ();} catch (FileNotFoundException e) {e.printStackTrace ();} catch (IOException e) {e.printStackTrace ();}} 3. Scalin
By reducing the pixel size of a picture to reduce its disk space and memory size, it can be used to cache thumbnails.
/ * scale bitmap * @ param context * @ param id * @ param maxW * @ param maxH * @ return * / public static Bitmap resizeBitmap (Context context,int id,int maxW,int maxH,boolean hasAlpha,Bitmap reusable) {Resources resources = context.getResources (); BitmapFactory.Options options = new BitmapFactory.Options () / only decode outxxx parameters such as width and height options.inJustDecodeBounds = true; BitmapFactory.decodeResource (resources,id,options); / / scale according to width and height int w = options.outWidth; int h = options.outHeight; / / set the scaling factor options.inSampleSize = calcuteInSampleSize If (! hasAlpha) {options.inPreferredConfig = Bitmap.Config.RGB_565;} options.inJustDecodeBounds = false; / / set to reusable options.inMutable=true; options.inBitmap=reusable; return BitmapFactory.decodeResource (resources,id,options) } / * calculate the scaling factor * @ param w * @ param h * @ param maxW * @ param maxH * @ return scaling factor * / private static int calcuteInSampleSize (int wmint hint maxW,int maxH) {int inSampleSize = 1; if (w > maxW & & h > maxH) {inSampleSize = 2 / / cycle to make the width and height less than the maximum width and height while (w / inSampleSize > maxW & & h / inSampleSize > maxH) {inSampleSize * = 2;}} return inSampleSize;}}
Using the JPEG library, use Huffman algorithm to compress the picture at the jni layer
Android's image engine uses a castrated version of the skia engine, eliminating the Huffman algorithm in image compression.
Void write_JPEG_file (uint8_t * data, int w, int h, jint Q, const char * path) {/ / 3.1, create jpeg compressed object jpeg_compress_struct jcs; / / error callback jpeg_error_mgr error; jcs.err = jpeg_std_error (& error); / / create compressed object jpeg_create_compress (& jcs) / / 3.2.specify the storage file write binary FILE * f = fopen (path, "wb"); jpeg_stdio_dest (& jcs, f); / / 3.3.set the compression parameter jcs.image_width = w; jcs.image_height = h; / / bgr jcs.input_components = 3; jcs.in_color_space = JCS_RGB; jpeg_set_defaults (& jcs) / / enable Huffman function jcs.optimize_coding = true; jpeg_set_quality (& jcs, Q, 1); / / 3.4.start compressing jpeg_start_compress (& jcs, 1); / / 3.5.Loop to write each row of data int row_stride = w * 3 bytes per row of JSAMPROW row / row [1] While (jcs.next_scanline < jcs.image_height) {/ / fetch a row of data uint8_t * pixels = data + jcs.next_scanline * row_stride; row [0] = pixels; jpeg_write_scanlines (& jcs,row,1);} / / 3.6.Compression completes jpeg_finish_compress (& jcs); / / 3.7, release jpeg object fclose (f) Jpeg_destroy_compress (& jcs);}
Because it is related to the jni part, I will only post the code for use for the time being, and I will write some jni blog to share with you later.
Set the picture to be reused
Picture reuse mainly refers to the reuse of memory blocks, there is no need to re-apply for a new piece of memory for the bitmap, avoiding a memory allocation and recycling, thus improving the running efficiency.
It should be noted that inBitmap can only be used after 3. 0. Bitmap data is stored in the memory area of native, not on the memory heap of Dalvik.
With inBitmap, before 4.4, only the memory area of the same size bitmap can be reused, but after 4.4, you can reuse the memory area of any bitmap, as long as the memory is larger than the bitmap that will be allocated. The best way to do this is to use LRUCache to cache bitmap, followed by a new bitmap, and you can find the most suitable bitmap for reuse according to the api version in cache to reuse its memory area.
BitmapFactory.Options options = new BitmapFactory.Options (); / / only decode outxxx parameters such as width and height options.inJustDecodeBounds = true; BitmapFactory.decodeResource (resources,id,options); / / scale according to width and height int w = options.outWidth; int h = options.outHeight; / / set the scaling factor options.inSampleSize = calcuteInSampleSize If (! hasAlpha) {options.inPreferredConfig = Bitmap.Config.RGB_565;} options.inJustDecodeBounds = false; / / set to reuse options.inMutable=true; options.inBitmap=reusable
Use picture caching
There is a LruCache in android, which is a thread-safe data cache class based on the least-used algorithm. When the set cache capacity is exceeded, the LRU cache strategy that gives priority to eliminating the most recently used data LruCache is implemented by LinkedHashMap, and controls the cache size and eliminates elements by encapsulating get/put and other related methods, but does not support key and value for null. We can use github.com/JakeWharton, an open source library provided by JakeWharton. To implement the logic of our picture cache
The memory and disk parts are omitted.
Thank you for your reading, these are the contents of "what is Android's bitmap picture optimization method?" after the study of this article, I believe you have a deeper understanding of what Android's bitmap picture optimization method is, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.