官方文檔Large Image Downsizing
https://developer.apple.com/library/content/samplecode/LargeImageDownsizing/Introduction/Intro.html
#define bytesPerMB 1048576.0f //1MB=1024KB=1024*1024字節(jié)
#define bytesPerPixel 4.0f //1像素4字節(jié)
#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;
//根據(jù)機(jī)型設(shè)置 期望的未壓縮的圖片大小 kDestImageSizeMB, 并 * pixelsPerMB = destTotalPixels (期望的像素大小)
//計(jì)算出壓縮倍數(shù)
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的每一行在內(nèi)存所占的比特?cái)?shù)
int bytesPerRow = bytesPerPixel * destResolution.width;
// allocate enough pixel data to hold the output image.
void* destBitmapData = malloc( bytesPerRow * destResolution.height );
// create the output bitmap context
destContext = CGBitmapContextCreate( destBitmapData, destResolution.width, destResolution.height, 8,
bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast );
//通過(guò)調(diào)用CGContextTranslateCTM函數(shù)來(lái)修改每個(gè)點(diǎn)的x, y坐標(biāo)值
CGContextTranslateCTM( destContext, 0.0f, destResolution.height );
//縮放操作根據(jù)指定的x, y因子來(lái)改變坐標(biāo)空間的大小蛋叼,從而放大或縮小圖像。
//x, y因子的大小決定了新的坐標(biāo)空間是否比原始坐標(biāo)空間大或者小奏司。
//另外千所,通過(guò)指定x因子為負(fù)數(shù),可以倒轉(zhuǎn)x軸厢汹,同樣可以指定y因子為負(fù)數(shù)來(lái)倒轉(zhuǎn)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
//設(shè)置壓縮時(shí)對(duì)于源圖像使用到的*塊*的最大字節(jié)數(shù)涩搓。
//The tile size will be (x)MB of uncompressed image data.
#define tileTotalPixels kSourceImageTileSizeMB * pixelsPerMB
sourceTile.size.height = (int)( tileTotalPixels / sourceTile.size.width );
函數(shù)原型:
CGContextRef CGBitmapContextCreate (
void *data,
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bytesPerRow,
CGColorSpaceRef colorspace,
CGBitmapInfo bitmapInfo
);
參數(shù):
data 指向要渲染的繪制內(nèi)存的地址脖阵。這個(gè)內(nèi)存塊的大小至少是(bytesPerRow*height)個(gè)字節(jié)
width bitmap的寬度,單位為像素
height bitmap的高度,單位為像素
bitsPerComponent 內(nèi)存中像素的每個(gè)組件的位數(shù).例如皂股,對(duì)于32位像素格式和RGB 顏色空間,你應(yīng)該將這個(gè)值設(shè)為8.
bytesPerRow bitmap的每一行在內(nèi)存所占的比特?cái)?shù)
colorspace bitmap上下文使用的顏色空間命黔。
bitmapInfo 指定bitmap是否包含alpha通道呜呐,像素中alpha通道的相對(duì)位置,像素組件是整形還是浮點(diǎn)型等信息的字符串纷铣。
描述:
當(dāng)你調(diào)用這個(gè)函數(shù)的時(shí)候卵史,Quartz創(chuàng)建一個(gè)位圖繪制環(huán)境战转,也就是位圖上下文搜立。當(dāng)你向上下文中繪制信息時(shí),
Quartz把你要繪制的信息作為位圖數(shù)據(jù)繪制到指定的內(nèi)存塊槐秧。
一個(gè)新的位圖上下文的像素格式由三個(gè)參數(shù)決定:
每個(gè)組件的位數(shù)啄踊,顏色空間忧设,alpha選項(xiàng)。alpha值決定了繪制像素的透明性颠通。
iOS kCGImageAlphaPremultipliedLast與kCGImageAlphaLast區(qū)別和聯(lián)系
原文 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 ,那么每個(gè)顏色分量是否已經(jīng)乘以 alpha 的值牢撼,這種做法可以加速圖片的渲染時(shí)間匙隔,因?yàn)樗苊饬虽秩緯r(shí)的額外乘法運(yùn)算。比如熏版,對(duì)于 RGB 顏色空間纷责,用已經(jīng)乘以 alpha 的數(shù)據(jù)來(lái)渲染圖片,每個(gè)像素都可以避免 3 次乘法運(yùn)算撼短,紅色乘以 alpha 再膳,綠色乘以 alpha 和藍(lán)色乘以 alpha 。
那么我們?cè)诮鈮嚎s圖片的時(shí)候應(yīng)該使用哪個(gè)值呢阔加?根據(jù) [Which CGImageAlphaInfo should we use](http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use)和官方文檔中對(duì) UIGraphicsBeginImageContextWithOptions 函數(shù)的討論:
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).
我們可以知道饵史,當(dāng)圖片不包含 alpha 的時(shí)候使用 kCGImageAlphaNoneSkipFirst ,否則使用 kCGImageAlphaPremultipliedFirst 胜榔。
alpha 通道布局信息胳喷,實(shí)際上也有一個(gè)枚舉值:
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 */
};
上面的注釋其實(shí)寫(xiě)很清楚,如果沒(méi)有 alhpa 分量夭织,那就是 kCGImageAlphaNone吭露。帶有 skip 的兩個(gè) kCGImageAlphaNoneSkipLast和kCGImageAlphaNoneSkipFirst即有 alpha 分量,但是忽略該值尊惰,相當(dāng)于透明度不起作用讲竿。kCGImageAlphaOnly只有 alpha 值,沒(méi)有顏色值弄屡。另外 4 個(gè)都表示帶有 alpha 通道题禀。帶有 Premultiplied,說(shuō)明在圖片解碼壓縮的時(shí)候膀捷,就將 alpha 通道的值分別乘到了顏色分量上迈嘹,我們知道 alpha 就會(huì)影響顏色的透明度,我們?nèi)绻趬嚎s的時(shí)候就將這步做掉了,那么渲染的時(shí)候就不必再處理 alpha 通道了秀仲,這樣可以提高渲染速度融痛。First 和 Last的區(qū)別就是 alpha 分量是在像素存儲(chǔ)的哪一邊。例如一個(gè)像素點(diǎn)32位神僵,表示4個(gè)分量雁刷,那么從左到右,如果是 ARGB保礼,就表示 alpha 分量在 first沛励,RGBA 就表示 alpha 分量在 last。
綜上可知:kCGImageAlphaPremultipliedLast提前把a(bǔ)lpha信息和RGB做了相乘已經(jīng)把計(jì)算結(jié)果計(jì)算好了炮障,這樣在顯示位圖的時(shí)候直接顯示就行了侯勉,這樣就提高了性能,而kCGImageAlphaLast沒(méi)有計(jì)算alpha的值铝阐,這樣的話在顯示位圖的時(shí)候就需要計(jì)算alpha信息址貌,導(dǎo)致性能低下。能使用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/)