利用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];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260