利用Quarzt2D的接口实现UIImage转换成像素点,以及UIImage像素数据翻转。

我们都知道图片是由很多个像素点组成的,而iOS中的图片通常又由UIImage承载。
如果我们想查看一张图片的每个像素点应该怎么做呢?或者如果我们有一堆像素点的数据,要怎么才能转换成UIImage呢?再或者我们想对一些图片进行像素点的处理应该怎么做呢?

1.第一个问题,把UIImage转换成像素点数据

UIImage转换成像素点需要用到一个Quartz的接口CGBitmapContextCreate。
听这个名字就知道这是用来创建位图上下文的。

CG_EXTERN CGContextRef CGBitmapContextCreate(
void *data, //如果data非空,指向一个内存区域,大小至少bytesPerRow *height的字节。如果data为空,data上下文自动分配和释放收回。
size_t width, //像素宽
size_t height, //像素高
size_t bitsPerComponent,  //位的数量为每个组件的指定一个像素
size_t bytesPerRow, //每一行的位图的字节,至少要宽*每个像素的字节
CGColorSpaceRef space,  //指定一个颜色空间
CGBitmapInfo bitmapInfo //指定位图是否应该包含一个alpha通道和它是如何产生的,以及是否组件是浮点或整数
)

所以只要根据CGBitmapContextCreate需要的参数就能得出image的像素点数据,方法如下:

    CGImageRef inputCGImage = [image CGImage];
    NSUInteger width = CGImageGetWidth(inputCGImage);
    NSUInteger height = CGImageGetHeight(inputCGImage);
    
    CGRect rect = CGRectMake(0, 0, width, height);
    
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel *width;
    NSUInteger bitsPerComponent = 8;
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  //色彩空间
   unsigned char * imagedata=malloc(width*height*bytesPerPixel);  //分配内存空间
    CGContextRef context =  CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);  //创建位图上下文
    CGContextDrawImage(context, rect, inputCGImage);
    CGColorSpaceRelease(colorSpace);  //内存释放
    CGContextRelease(context);

这样imagedata就是我们需要的像素点数据了。

2.第二个问题,怎么把像素点转换成UIImage。

这次我们同样要用到Quartz的接口:CGDataProviderCreateWithData
根据接口名字我们能知道这是一个创建dataprovider的接口。


CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, imagedata, bytesPerRow * height, NULL);  //创建provider
    CGImageRef imageRef = CGImageCreate(width, height, 8, 32, bytesPerRow, colorSpace,
                                        kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
                                        NULL, true, kCGRenderingIntentDefault);  //由provider创建CGImage
    CGDataProviderRelease(dataProvider);
    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];  //由CGImage创建UIImage
   
    CGImageRelease(imageRef);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

3.处理像素点。

有了方法1,我们就能拿到像素点了。我们可以按照喜好处理像素点。然后通过方法2把我们处理后的像素点转换成UIImage。
这里,举一个把像素点上下翻转的例子:
把方法1中的imageData转成Data方便我们传值:

size_t bufferLength = bytesPerRow * height;
    NSData* data = [NSData dataWithBytes:imageData length:bufferLength];

然后通过下面这个方法就可以翻转了。

+ (NSData*)downMirrorImageData:(NSData*)data width:(NSInteger)width height:(NSInteger)height bytesPerPixel:(NSInteger)bytesPerPixel
{
    if (!data || data.length == 0) return nil;
    
    unsigned char* buffer = (unsigned char*)[data bytes];
    for (NSInteger h = 0; h < height/2; h++) {
        for (NSInteger w = 0; w < width*bytesPerPixel; w++) {
            NSInteger targetH = height - 1 - h;
            NSInteger sourceIndex = w + width*bytesPerPixel*h;
            NSInteger targetIndex = w + width*bytesPerPixel*targetH;
            buffer[sourceIndex] = buffer[sourceIndex]+buffer[targetIndex];
            buffer[targetIndex] = buffer[sourceIndex] - buffer[targetIndex];
            buffer[sourceIndex] = buffer[sourceIndex] - buffer[targetIndex];
        }
    }
    return [NSData dataWithBytes:buffer length:width*height*bytesPerPixel];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。