A mutual conversion between CGImageRef and UIImage
CGImageRef is a structure pointer. Through CGImageRef, all parameters of UIImage can be obtained, such as pixel width and height, color channel bit depth, pixel bit depth, pixel byte arrangement and reading order, etc. The conversion between CGImageRef and UIImage is as follows :
Convert UIImage to CGImageRef
UIImage *image = [UIImage imageNamed:@"testImg"];
CGImageRef imageRef = image.CGImage;
Convert CGImageRef to UIImage
CGImageRef imageRef = [UIImage imageNamed:@"testImg"].CGImage;
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
Remember to release CGImageRef every time you use it, otherwise it will cause a memory leak. The release method is also very simple, as shown below:
CGImageRelease(imageRef);
Two CGImageRef creation method
Created using a png data source
Instructions
CGImageCreateWithPNGDataProvider(CGDataProviderRef cg_nullable source, const CGFloat * __nullable decode, bool shouldInterpolate, CGColorRenderingIntent intent)
Example usage:
NSString *path = [[NSBundle mainBundle] pathForResource:@"bundle8Bit" ofType:@".png"];
NSData *bundleImgData = [NSData dataWithContentsOfFile:path];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)bundleImgData);
CGImageRef imageRef = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
self.imageV.image = image;
Created using a jpeg data source
Instructions
CGImageCreateWithJPEGDataProvider(CGDataProviderRef cg_nullable source, const CGFloat * __nullable decode, bool shouldInterpolate, CGColorRenderingIntent intent)
Example usage:
NSString *path = [[NSBundle mainBundle] pathForResource:@"houst" ofType:@".jpg"];
NSData *bundleImgData = [NSData dataWithContentsOfFile:path];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)bundleImgData);
CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
self.imageV.image = image;
Created using a matrix data source
Using matrix data sources to create pictures is the most flexible method, which can basically fully meet all our customization needs, and can implement pixel-level changes to pictures, using the method name
CGImageCreate(size_t width, size_t height,size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGColorSpaceRef cg_nullable space, CGBitmapInfo bitmapInfo,CGDataProviderRef cg_nullable provider,const CGFloat * __nullable decode, bool shouldInterpolate,CGColorRenderingIntent intent)
The parameters are parsed as follows:
size_t width image width (pixel level)
size_t height image height (pixel level)
size_t bitsPerComponent bit depth of each pixel channel (number of bits)
size_t bitsPerPixel bit depth of each pixel point (number of bits)
size_t bytesPerRow pixel space per row Size (in bytes)
CGColorSpaceRef cg_nullable space Color space
CGBitmapInfo bitmapInfo Pixel arrangement and reading order
CGDataProviderRef cg_nullable provider Data supply source
const CGFloat * __nullable decode Decode arrr Generally pass in null to keep source data
bool shouldInterpolate Whether to use difference to smooth transition image
CGColorRenderingIntent The way intents map from one color space to another
How to use
//创建一个宽2000像素 高3000像素 每通道8bit 一共三通道(无alpha通道) 使用rgb颜色空间 的一张纯红色的图片
size_t imageWidth = 2000;
size_t imageHeight = 3000;
size_t bitsPerComponent = 8;
size_t bitsPerPixel = 24;
size_t bytesPerRow = imageWidth * bitsPerPixel / 8;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGImageByteOrderDefault;
//创建纯红色数据源
int byteIndex = 0;
unsigned char *rawData = (unsigned char*) malloc(imageWidth * imageHeight * 3);
for (int i = 0; i < imageHeight; i ++) {
for (int j = 0; j < imageWidth; j ++) {
rawData[byteIndex ++] = 255; //red通道
rawData[byteIndex ++] = 0; //green通道
rawData[byteIndex ++] = 0; //blue通道
}
}
CGDataProviderRef dataProviderRef = CGDataProviderCreateWithData(NULL,
rawData,
imageWidth*imageHeight*3,
NULL);
CGImageRef imageRef = CGImageCreate(imageWidth,
imageHeight,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
dataProviderRef,
nil,
NO,
kCGRenderingIntentDefault);
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(dataProviderRef);
CGImageRelease(imageRef);
self.imageV.image = image;
Creation result
Output image information check:
size_t bitsPerComponentCheck = CGImageGetBitsPerComponent(imageRef);
printf("每个通道占用的位数:%zu\n",bitsPerComponentCheck);
size_t bitsPerPixelCheck = CGImageGetBitsPerPixel(imageRef);
printf("每个像素占用的位数:%zu",bitsPerPixelCheck);
输出结果:
每个通道占用的位数:8
每个像素占用的位数:24
Consistent with the parameters we created
Three use CGImageRef to crop the picture
方法 CGImageCreateWithImageInRect(CGImageRef cg_nullable image, CGRect rect)
A few examples of usage methods are as follows
NSString *path = [[NSBundle mainBundle] pathForResource:@"bundle8Bit" ofType:@".png"];
NSData *bundleImgData = [NSData dataWithContentsOfFile:path];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)bundleImgData);
CGImageRef imageRef = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
CGImageRef clipImageRef = CGImageCreateWithImageInRect(imageRef, CGRectMake(0, 0, 100, 200));
UIImage *image = [UIImage imageWithCGImage:clipImageRef];
self.imageV.image = image;
Take the upper left corner of the picture as the vertex, and crop the picture area with a pixel width of 100 and a height of 200.
Crop the original picture:
Cropped picture:
Source code download: Source code download