Use CGImageRef to create pictures and realize picture area cropping (with source code)

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
insert image description here
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:
insert image description here
Cropped picture:
insert image description here
Source code download: Source code download

Guess you like

Origin blog.csdn.net/mumubumaopao/article/details/130756475