有兩種方式
1、通過獲取繪圖上下文,將圖片繪制到上下文中,然后從上下文中取出這個圖片(優點就是,繪圖過程會對圖片做優化處理)
2、通過CGDataProviderCopyData( CGDataProviderRef cg_nullable provider)進行解碼
說明:[UIImage imageNamed:@"name"]得到的圖片是已經解碼的圖片,並且將這個解碼好的圖片緩存了起來。
第一種實現方式如下:
//將要解碼的圖片 UIImage *img = [[UIImage alloc] initWithContentsOfFile:@"..."]; CGImageRef imageRef = img.CGImage; CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef) & kCGBitmapAlphaInfoMask; BOOL hasAlpha = NO; if (alphaInfo == kCGImageAlphaPremultipliedLast || alphaInfo == kCGImageAlphaPremultipliedFirst || alphaInfo == kCGImageAlphaLast || alphaInfo == kCGImageAlphaFirst) { hasAlpha = YES; } // BGRA8888 (premultiplied) or BGRX8888 // same as UIGraphicsBeginImageContext() and -[UIView drawRect:] CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host; bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 0, YYCGColorSpaceGetDeviceRGB(), bitmapInfo); if (!context) return NULL; CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); // 圖片解碼 CGImageRef newImage = CGBitmapContextCreateImage(context); CFRelease(context); UIImage *decodedImg = [UIImage imageWithCGImage:newImage]; // 解碼后的圖片
第二種方式如下:
//將要解碼的圖片 UIImage *img = [[UIImage alloc] initWithContentsOfFile:@"..."]; CGImageRef imageRef = img.CGImage; CGColorSpaceRef space = CGImageGetColorSpace(imageRef); size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); if (bytesPerRow == 0 || width == 0 || height == 0) return NULL; CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef); if (!dataProvider) return NULL; CFDataRef data = CGDataProviderCopyData(dataProvider); // 對圖片解碼 if (!data) return NULL; CGDataProviderRef newProvider = CGDataProviderCreateWithCFData(data); CFRelease(data); if (!newProvider) return NULL; CGImageRef newImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, space, bitmapInfo, newProvider, NULL, false, kCGRenderingIntentDefault); CFRelease(newProvider); UIImage *decodedImg = [UIImage imageWithCGImage:newImage]; // 解碼后的圖片
以上就是手動解碼的過程,解碼的目的就是為了讓圖像渲染引擎將圖片繪制到屏幕上
如果我們不手動解碼,並且圖片不是通過[UIImage imageNamed:@"name"]創建的,UIImage是不會對圖片進行解碼的
那系統是在什么時候解碼的呢?
其實顯示到屏幕上的圖層的繪制是由一個獨立與app的渲染引擎操作的,這個引擎只接收解碼好的圖片,然后只接繪制到屏幕上(可能是出於效率考慮)。那么圖片的解碼操作也就是在這個圖片將要讓渲染引擎繪制的時候進行的,這個操作是在app內部完成的。
為什么需要手動解碼?
目的只有一個,那就是提高顯示過程的效率。如果一個圖片已經提前解碼好了,那么在顯示的過程中,就不需要再次解碼了,解碼的過程是很消耗性能的,從而提高了圖片的加載速度。