如下方法:
(下面內容要全復制)
#pragma mark - 馬賽克處理
static CGContextRef CreateRGBABitmapContext (CGImageRef inImage)
{
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void *bitmapData; //內存空間的指針,該內存空間的大小等于圖像使用RGB通道所占用的字節數。
int bitmapByteCount;
int bitmapBytesPerRow;
size_t pixelsWide = CGImageGetWidth(inImage); //獲取橫向的像素點的個數
size_t pixelsHigh = CGImageGetHeight(inImage);
bitmapBytesPerRow ? ?= (pixelsWide * 4); //每一行的像素點占用的字節數,每個像素點的ARGB四個通道各占8個bit(0-255)的空間
bitmapByteCount ? ?= (bitmapBytesPerRow * pixelsHigh); //計算整張圖占用的字節數
colorSpace = CGColorSpaceCreateDeviceRGB();//創建依賴于設備的RGB通道
//分配足夠容納圖片字節數的內存空間
bitmapData = malloc( bitmapByteCount );
//創建CoreGraphic的圖形上下文,該上下文描述了bitmaData指向的內存空間需要繪制的圖像的一些繪制參數
context = CGBitmapContextCreate (bitmapData,pixelsWide,pixelsHigh,8,bitmapBytesPerRow,colorSpace,kCGImageAlphaPremultipliedLast);
//Core Foundation中通過含有Create、Alloc的方法名字創建的指針,需要使用CFRelease()函數釋放
CGColorSpaceRelease( colorSpace );
return context;
}
static unsigned char *RequestImagePixelData(UIImage *inImage)
{
CGImageRef img = [inImage CGImage];
CGSize size = [inImage size];
//使用上面的函數創建上下文
CGContextRef cgctx = CreateRGBABitmapContext(img);
CGRect rect = {{0,0},{size.width, size.height}};
//將目標圖像繪制到指定的上下文,實際為上下文內的bitmapData。
CGContextDrawImage(cgctx, rect, img);
unsigned char *data = CGBitmapContextGetData (cgctx);
//釋放上面的函數創建的上下文
CGContextRelease(cgctx);
return data;
}
/*
*轉換成馬賽克,level代表一個點轉為多少level*level的正方形
*/
+ (UIImage *)transToMosaicImage:(UIImage*)orginImage blockLevel:(NSUInteger)level
{
//獲取BitmapData
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef imgRef = orginImage.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGContextRef context = CGBitmapContextCreate (nil,
width,
height,
kBitsPerComponent, ? ? ? ?//每個顏色值8bit
width*kPixelChannelCount, //每一行的像素點占用的字節數,每個像素點的ARGB四個通道各占8個bit
colorSpace,
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imgRef);
unsigned char *bitmapData = CGBitmapContextGetData (context);
//這里把BitmapData進行馬賽克轉換,就是用一個點的顏色填充一個level*level的正方形
unsigned char pixel[kPixelChannelCount] = {0};
NSUInteger index,preIndex;
for (NSUInteger i = 0; i < height - 1 ; i++) {
for (NSUInteger j = 0; j < width - 1; j++) {
index = i * width + j;
if (i % level == 0) {
if (j % level == 0) {
memcpy(pixel, bitmapData + kPixelChannelCount*index, kPixelChannelCount);
}else{
memcpy(bitmapData + kPixelChannelCount*index, pixel, kPixelChannelCount);
}
} else {
preIndex = (i-1)*width +j;
memcpy(bitmapData + kPixelChannelCount*index, bitmapData + kPixelChannelCount*preIndex, kPixelChannelCount);
}
}
}
NSInteger dataLength = width*height* kPixelChannelCount;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmapData, dataLength, NULL);
//創建要輸出的圖像
CGImageRef mosaicImageRef = CGImageCreate(width, height,
kBitsPerComponent,
kBitsPerPixel,
width*kPixelChannelCount ,
colorSpace,
kCGImageAlphaPremultipliedLast,
provider,
NULL, NO,
kCGRenderingIntentDefault);
CGContextRef outputContext = CGBitmapContextCreate(nil,
width,
height,
kBitsPerComponent,
width*kPixelChannelCount,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(outputContext, CGRectMake(0.0f, 0.0f, width, height), mosaicImageRef);
CGImageRef resultImageRef = CGBitmapContextCreateImage(outputContext);
UIImage *resultImage = nil;
if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
// ? ? ? ?float scale = [[UIScreen mainScreen] scale];
// ? ? ? ?resultImage = [UIImage imageWithCGImage:resultImageRef scale:scale orientation:UIImageOrientationUp];
resultImage = [UIImage imageWithCGImage:resultImageRef scale:orginImage.scale orientation:orginImage.imageOrientation];
} else {
resultImage = [UIImage imageWithCGImage:resultImageRef];
}
//釋放
if(resultImageRef){
CFRelease(resultImageRef);
}
if(mosaicImageRef){
CFRelease(mosaicImageRef);
}
if(colorSpace){
CGColorSpaceRelease(colorSpace);
}
if(provider){
CGDataProviderRelease(provider);
}
if(context){
CGContextRelease(context);
}
if(outputContext){
CGContextRelease(outputContext);
}
// ? ?return [[resultImage retain] autorelease];
return resultImage;
}