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 introduces how to load pictures efficiently in iOS. It is very detailed and has certain reference value. Friends who are interested must finish reading it.
The rendering process of pictures
Using UIImage and UIImageView to record pictures in iOS, they follow the classic MVC architecture, and UIImage is equivalent to Model,UIImageView and View:
UIImage is responsible for loading pictures, and UIImageView is responsible for rendering pictures.
The rendering process of the picture is divided into three stages: loading (Load), decoding (Decoder) and rendering (Render).
At each stage, there are corresponding buffers: data buffer (DataBuffer), image buffer (imageBuffer) and frame buffer (framebuffer).
We take an image with a size of 2048 px * 1536 px and a size of 590kb on disk as an example to analyze the buffers of the first two stages.
DataBuffer
A DataBuffer is simply a buffer that contains a series of bytes. It usually starts with some metadata, which describes the size of the image stored in the data buffer, including the graphic data itself, which is encoded in some form, such as JPEG compression or PNG, which means that the byte does not directly describe any content of the pixels in the image. At this time, the DataBuffer size is 590kb.
SD source code analysis
In SDWebImage, after the picture is loaded, in the sd_imageFormatForImageData method, the format of the picture is determined by the first byte of the DataBuffer.
Uint8_t c; [data getBytes:&c length:1]; switch (c) {case 0xFF: return SDImageFormatJPEG; case 0x89: return SDImageFormatPNG; case 0x47: retur SDImageFormatGIF; case 0x49: case 0x4D: return SDImageFormatTIFF;. } ImageBuffer
After the picture is loaded, the JPEG,PNG or other encoded data of Data Buffer need to be converted into the image information of each pixel. This process, called Decoder (decoding), stores the pixel information in ImageBuffer.
Occupied memory size
The amount of memory occupied by an image is related to the size of the image, regardless of its file size. In the iOSSRGB display format (4byte space displays one pixel), if you parse all the pixels, you need 2048 px * 1536 px * 4byte / px = 10MB, and the size of the ImageBuffer is 10MB.
After the ImageBuffer parsing, submit it to frameBuffer for rendering and display.
In general, the picture loading process and the memory consumed are shown in the following figure:
Xcode test
In the Xcode project, when you push a new page, only one image is loaded.
Pre-load memory value:
Memory value after loading:
In most cases, we do not need to display pictures with such high precision, which takes up so much memory, can we reduce the memory value used when loading pictures?
How to reduce the memory consumption of images
Downward sampling
In Apple's official documentation, it is recommended that we use downsampling (Downsampleing) technology to load images and reduce the size of ImageBuffer.
The methods are as follows:
Func downsample (imageAt imageURL: URL, to pointSize:CGSize, scale:CGFloat)-> UIImage {let imageSourcesOptions = [kCGImageSourceShouldCache: false] as CFDictionary let imageSource = CGImageSourceCreateWithURL (imageURL as CFURL, imageSourcesOptions)! Let maxDimensionInPixels = max (pointSize.width, pointSize.height) * scale let downsampleOptions = [kCGImageSourceCreateThumbnailFromImageAlways: true, kCGImageSourceShouldCacheImmediately: true, kCGImageSourceCreateThumbnailWithTransform: true, kCGImageSourceThumbnailMaxPixelSize:maxDimensionInPixels] as CFDictionary let downsampledImage = CGImageSourceCreateThumbnailAtIndex (imageSource, 0, downsampleOptions)! Return UIImage (cgImage: downsampledImage)}
Let's test it:
Let imageStr = Bundle.main.path (forResource: "view_site.jpeg", ofType: nil) let imageURL = URL (string: "file://" + (imageStr?")) Guard let imgURL = imageURL else {return} imageView.image = downsample (imageAt:imgURL, to: CGSize (width: 200,200), scale: UIScreen.main.scale)
13m before loading and 17m after loading, the effect is obvious, saving about 5m of memory space.
When compressing the picture, we should choose the down sampling technique.
SD source code analysis and decoding process
In SDWebIamge, there are three types of decoders: SDImageIOCoder, SDImageGIFCoder, and SDImageAPNGCoder. According to the encoding type of DataBuffer, the corresponding encoder is used.
In the-(UIImage *) decodedImageWithData: (NSData *) data method, configure the decoding parameters and start the decoding operation.
Complete image decoding in + (UIImage *) createFrameAtIndex: (NSUInteger) index source: (CGImageSourceRef) source scale: (CGFloat) scale preserveAspectRatio: (BOOL) preserveAspectRatio thumbnailSize: (CGSize) thumbnailSize options: (NSDictionary) options
Choose the correct picture rendering format
Rendering format
In iOS, there are four rendered picture formats
Alpha 8 Format:1 bytes display 1 pixel, good at displaying monotone pictures.
Luminance and alpha 8 format: brightness and alpha 8 format, 2 bytes display 1 pixel, good at displaying transparent monotone pictures.
SRGB Format: 4 bytes show 1 pixel.
Wide Format: wide color gamut format, 8 bytes display 1 pixel. Suitable for high-precision pictures
How to choose the rendering format correctly
The correct idea is: do not choose the rendering format, let the rendering format choose you.
Replace UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRender, the former will automatically choose the rendering format after iOS12, and the latter will choose SRGB Format by default.
Func render ()-> UIImage {let bounds = CGRect (x: 0, y: 0, width: 300, height: 100) let render = UIGraphicsImageRenderer (size: bounds.size) let image = render.image {context in UIColor.blue.setFill () let path = UIBezierPath (roundedRect: bounds, byRoundingCorners: UIRectCorner.allCorners, cornerRadii: CGSize (width: 20, height: 20) path.addClip () UIRectFill (bounds)} return image}
At this point, the content footprint will be reduced by 75% for the system to automatically select the Alpha 8 Format format.
Reduce the use of backup memory
Reduce or not use the draw (rect:) method
When you need to draw a View with child views, do not use the draw (rect:) method, use the View property of the system or add child views, and leave the drawing work to the system to deal with.
The background color is set directly through UIView.backgroundColor instead of using draw (rect:)
How to load a picture in a list
In our development, the images are usually loaded asynchronously by sub-threads, decoded and downsampled in the background. In the list, sometimes a lot of pictures are loaded, so you should pay attention to the thread explosion.
Thread explosion
This happens when we ask the system to do more work than CPU can do, for example, we want to display eight pictures, but we only have two CPU, we can't do all this work at once, we can't do parallel processing on a non-existent CPU, to avoid deadlocks when asynchronously assigning tasks to a global queue, GCD will create a new thread to capture what we asked it to do. And then CPU will spend a lot of time switching between these threads, trying to make the gradual progress we asked the operating system to do for us on all the work, constantly switching between these threads is actually quite expensive, and now instead of simply assigning work to one of the global asynchronous queues, it's creating a serial queue to which work is asynchronously dispatched in the prefetch method. It does mean that the loading of a single image may start to make progress later than before, but CPU will spend less time switching back and forth between the small tasks it can do.
In SDWebImage, the decoded queue _ coderQueue.maxConcurrentOperationCount = 1 is a serial queue. This solves the problem of thread explosion when multiple images are decoded asynchronously.
The above is all the contents of the article "how to load pictures efficiently in iOS". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!
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.