Large|Large Image Downsizing

【Large|Large Image Downsizing】官方文档Large Image Downsizing
https://developer.apple.com/library/content/samplecode/LargeImageDownsizing/Introduction/Intro.html

#define bytesPerMB 1048576.0f//1MB=1024KB=1024*1024字节 #define bytesPerPixel 4.0f//1像素4字节 #define pixelsPerMB ( bytesPerMB / bytesPerPixel )//1MB中有多少像素//use the width and height to calculate the total number of pixels in the input image. sourceTotalPixels = sourceResolution.width * sourceResolution.height; //calculate the number of MB that would be required to store this image uncompressed in memory. sourceTotalMB = sourceTotalPixels / pixelsPerMB; //根据机型设置 期望的未压缩的图片大小 kDestImageSizeMB, 并 * pixelsPerMB = destTotalPixels (期望的像素大小) //计算出压缩倍数 imageScale = destTotalPixels / sourceTotalPixels; //得出期望的宽高 destResolution.width = (int)( sourceResolution.width * imageScale ); destResolution.height = (int)( sourceResolution.height * imageScale ); // create an offscreen bitmap context that will hold the output image pixel data, // as it becomes available by the downscaling routine. // use the RGB colorspace as this is the colorspace iOS GPU is optimized for. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); //bitmap的每一行在内存所占的比特数 int bytesPerRow = bytesPerPixel * destResolution.width; // allocate enough pixel data to hold the output image. void* destBitmapData = https://www.it610.com/article/malloc( bytesPerRow * destResolution.height ); // create the output bitmap context destContext = CGBitmapContextCreate( destBitmapData, destResolution.width, destResolution.height, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast ); //通过调用CGContextTranslateCTM函数来修改每个点的x, y坐标值 CGContextTranslateCTM( destContext, 0.0f, destResolution.height ); //缩放操作根据指定的x, y因子来改变坐标空间的大小,从而放大或缩小图像。 //x, y因子的大小决定了新的坐标空间是否比原始坐标空间大或者小。 //另外,通过指定x因子为负数,可以倒转x轴,同样可以指定y因子为负数来倒转y轴。 CGContextScaleCTM( destContext, 1.0f, -1.0f ); // sub rect of the input image bounds that represents the // maximum amount of pixel data to load into mem at one time. CGRect sourceTile; sourceTile.size.width = sourceResolution.width; kSourceImageTileSizeMB //设置压缩时对于源图像使用到的*块*的最大字节数。 //The tile size will be (x)MB of uncompressed image data. #define tileTotalPixels kSourceImageTileSizeMB * pixelsPerMB sourceTile.size.height = (int)( tileTotalPixels / sourceTile.size.width );

函数原型: CGContextRef CGBitmapContextCreate ( void *data, size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow, CGColorSpaceRef colorspace, CGBitmapInfo bitmapInfo ); 参数: data指向要渲染的绘制内存的地址。这个内存块的大小至少是(bytesPerRow*height)个字节 widthbitmap的宽度,单位为像素 heightbitmap的高度,单位为像素 bitsPerComponent内存中像素的每个组件的位数.例如,对于32位像素格式和RGB 颜色空间,你应该将这个值设为8. bytesPerRowbitmap的每一行在内存所占的比特数 colorspacebitmap上下文使用的颜色空间。 bitmapInfo指定bitmap是否包含alpha通道,像素中alpha通道的相对位置,像素组件是整形还是浮点型等信息的字符串。描述: 当你调用这个函数的时候,Quartz创建一个位图绘制环境,也就是位图上下文。当你向上下文中绘制信息时, Quartz把你要绘制的信息作为位图数据绘制到指定的内存块。 一个新的位图上下文的像素格式由三个参数决定: 每个组件的位数,颜色空间,alpha选项。alpha值决定了绘制像素的透明性。

iOS kCGImageAlphaPremultipliedLast与kCGImageAlphaLast区别和联系 原文 http://blog.csdn.net/jeffasd/article/details/78142067 typedef CF_ENUM(uint32_t, CGImageAlphaInfo) {kCGImageAlphaNone,/* For example, RGB. */kCGImageAlphaPremultipliedLast,/* For example, premultiplied RGBA */kCGImageAlphaPremultipliedFirst, /* For example, premultiplied ARGB */kCGImageAlphaLast,/* For example, non-premultiplied RGBA */kCGImageAlphaFirst,/* For example, non-premultiplied ARGB */kCGImageAlphaNoneSkipLast,/* For example, RBGX. */kCGImageAlphaNoneSkipFirst,/* For example, XRGB. */kCGImageAlphaOnly/* No color data, alpha data only */}; CGImageAlphaInfo包含以下信息:*是否包含 alpha ; *如果包含 alpha ,那么 alpha 信息所处的位置,在像素的[最低有效位](https://zh.wikipedia.org/wiki/%E6%9C%80%E4%BD%8E%E6%9C%89%E6%95%88%E4%BD%8D),比如 RGBA ,还是[最高有效位](https://zh.wikipedia.org/wiki/%E6%9C%80%E9%AB%98%E6%9C%89%E6%95%88%E4%BD%8D),比如 ARGB ; *如果包含 alpha ,那么每个颜色分量是否已经乘以 alpha 的值,这种做法可以加速图片的渲染时间,因为它避免了渲染时的额外乘法运算。比如,对于 RGB 颜色空间,用已经乘以 alpha 的数据来渲染图片,每个像素都可以避免 3 次乘法运算,红色乘以 alpha ,绿色乘以 alpha 和蓝色乘以 alpha 。那么我们在解压缩图片的时候应该使用哪个值呢?根据 [Which CGImageAlphaInfo should we use](http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use)和官方文档中对 UIGraphicsBeginImageContextWithOptions 函数的讨论:You use this function to configure the drawing environment for rendering into a bitmap. The format for the bitmap is a ARGB 32-bit integer pixel format using host-byte order. If the opaque parameter is YES, the alpha channel is ignored and the bitmap is treated as fully opaque (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host). Otherwise, each pixel uses a premultipled ARGB format (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host).我们可以知道,当图片不包含 alpha 的时候使用 kCGImageAlphaNoneSkipFirst ,否则使用 kCGImageAlphaPremultipliedFirst 。alpha 通道布局信息,实际上也有一个枚举值:typedef CF_ENUM(uint32_t, CGImageAlphaInfo) {kCGImageAlphaNone,/* For example, RGB. */kCGImageAlphaPremultipliedLast,/* For example, premultiplied RGBA */kCGImageAlphaPremultipliedFirst, /* For example, premultiplied ARGB */kCGImageAlphaLast,/* For example, non-premultiplied RGBA */kCGImageAlphaFirst,/* For example, non-premultiplied ARGB */kCGImageAlphaNoneSkipLast,/* For example, RBGX. */kCGImageAlphaNoneSkipFirst,/* For example, XRGB. */kCGImageAlphaOnly/* No color data, alpha data only */}; 上面的注释其实写很清楚,如果没有 alhpa 分量,那就是 kCGImageAlphaNone。带有 skip 的两个 kCGImageAlphaNoneSkipLast和kCGImageAlphaNoneSkipFirst即有 alpha 分量,但是忽略该值,相当于透明度不起作用。kCGImageAlphaOnly只有 alpha 值,没有颜色值。另外 4 个都表示带有 alpha 通道。带有 Premultiplied,说明在图片解码压缩的时候,就将 alpha 通道的值分别乘到了颜色分量上,我们知道 alpha 就会影响颜色的透明度,我们如果在压缩的时候就将这步做掉了,那么渲染的时候就不必再处理 alpha 通道了,这样可以提高渲染速度。First 和 Last的区别就是 alpha 分量是在像素存储的哪一边。例如一个像素点32位,表示4个分量,那么从左到右,如果是 ARGB,就表示 alpha 分量在 first,RGBA 就表示 alpha 分量在 last。综上可知:kCGImageAlphaPremultipliedLast提前把alpha信息和RGB做了相乘已经把计算结果计算好了,这样在显示位图的时候直接显示就行了,这样就提高了性能,而kCGImageAlphaLast没有计算alpha的值,这样的话在显示位图的时候就需要计算alpha信息,导致性能低下。能使用kCGImageAlphaPremultipliedLast就尽量使用。 参考文章: [http://blog.imerc.xyz/2017/07/09/ios-image-decode/](http://blog.imerc.xyz/2017/07/09/ios-image-decode/) [http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/](http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/)

    推荐阅读