利用Quarzt2D的接口實(shí)現(xiàn)UIImage轉(zhuǎn)換成像素點(diǎn),以及UIImage像素?cái)?shù)據(jù)翻轉(zhuǎn)。

我們都知道圖片是由很多個(gè)像素點(diǎn)組成的,而iOS中的圖片通常又由UIImage承載。
如果我們想查看一張圖片的每個(gè)像素點(diǎn)應(yīng)該怎么做呢?或者如果我們有一堆像素點(diǎn)的數(shù)據(jù),要怎么才能轉(zhuǎn)換成UIImage呢?再或者我們想對(duì)一些圖片進(jìn)行像素點(diǎn)的處理應(yīng)該怎么做呢?

1.第一個(gè)問(wèn)題,把UIImage轉(zhuǎn)換成像素點(diǎn)數(shù)據(jù)

UIImage轉(zhuǎn)換成像素點(diǎn)需要用到一個(gè)Quartz的接口CGBitmapContextCreate。
聽(tīng)這個(gè)名字就知道這是用來(lái)創(chuàng)建位圖上下文的。

CG_EXTERN CGContextRef CGBitmapContextCreate(
void *data, //如果data非空,指向一個(gè)內(nèi)存區(qū)域,大小至少bytesPerRow *height的字節(jié)。如果data為空,data上下文自動(dòng)分配和釋放收回。
size_t width, //像素寬
size_t height, //像素高
size_t bitsPerComponent,  //位的數(shù)量為每個(gè)組件的指定一個(gè)像素
size_t bytesPerRow, //每一行的位圖的字節(jié),至少要寬*每個(gè)像素的字節(jié)
CGColorSpaceRef space,  //指定一個(gè)顏色空間
CGBitmapInfo bitmapInfo //指定位圖是否應(yīng)該包含一個(gè)alpha通道和它是如何產(chǎn)生的,以及是否組件是浮點(diǎn)或整數(shù)
)

所以只要根據(jù)CGBitmapContextCreate需要的參數(shù)就能得出image的像素點(diǎn)數(shù)據(jù),方法如下:

    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);  //分配內(nèi)存空間
    CGContextRef context =  CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);  //創(chuàng)建位圖上下文
    CGContextDrawImage(context, rect, inputCGImage);
    CGColorSpaceRelease(colorSpace);  //內(nèi)存釋放
    CGContextRelease(context);

這樣imagedata就是我們需要的像素點(diǎn)數(shù)據(jù)了。

2.第二個(gè)問(wèn)題,怎么把像素點(diǎn)轉(zhuǎn)換成UIImage。

這次我們同樣要用到Quartz的接口:CGDataProviderCreateWithData
根據(jù)接口名字我們能知道這是一個(gè)創(chuàng)建dataprovider的接口。


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

3.處理像素點(diǎn)。

有了方法1,我們就能拿到像素點(diǎn)了。我們可以按照喜好處理像素點(diǎn)。然后通過(guò)方法2把我們處理后的像素點(diǎn)轉(zhuǎn)換成UIImage。
這里,舉一個(gè)把像素點(diǎn)上下翻轉(zhuǎn)的例子:
把方法1中的imageData轉(zhuǎn)成Data方便我們傳值:

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

然后通過(guò)下面這個(gè)方法就可以翻轉(zhuǎn)了。

+ (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];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容