之前做了一下相關塗鴉的東西,發現圖片處理挺好玩的,就先講講馬賽克的實現吧。
放大馬賽克圖片可以看到,可以看到一個個單色的小正方形。所以馬賽克其實也就是把某一點的色值填充了它一定范圍內的一個正方形,這樣看起來就會模糊,但整體還是有一定原來的樣子。如圖,一張圖片可以認為是9*9個色值組成的位圖,進行馬賽克轉換就變成:
轉換為
可知,就是把某一位的色值向右向下填充一個2*2的正方形。
iOS代碼如下:
#define kBitsPerComponent (8) #define kBitsPerPixel (32) #define kPixelChannelCount (4) /* *轉換成馬賽克,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]; } 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]; }
其實主要代碼就是里面那層做的馬賽克轉換,前后都是為了獲取bitmapdata和把bitmapdata再還原為圖像。
大家可以看看效果吧,這里level選為10.(圖片來自百度百科,不涉及侵權哈)
發現圖片處理確實挺好玩的。