放大马赛克图片可以看到,可以看到一个个单色的小正方形。所以马赛克其实也就是把某一点的色值填充了它一定范围内的一个正方形,这样看起来就会模糊,但整体还是有一定原来的样子。如图,一张图片可以认为是9*9个色值组成的位图,进行马赛克转换就变成:
转换为
可知,就是把某一位的色值向右向下填充一个2*2的正方形。
1 + (UIImage *)transToMosaicImage:(UIImage*)orginImage blockLevel:(NSUInteger)level 2 { 3 //获取BitmapData 4 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 5 CGImageRef imgRef = orginImage.CGImage; 6 CGFloat width = CGImageGetWidth(imgRef); 7 CGFloat height = CGImageGetHeight(imgRef); 8 CGContextRef context = CGBitmapContextCreate (nil, 9 width,10 height,11 kBitsPerComponent, //每个颜色值8bit12 width*kPixelChannelCount, //每一行的像素点占用的字节数,每个像素点的ARGB四个通道各占8个bit13 colorSpace,14 kCGImageAlphaPremultipliedLast);15 CGContextDrawImage(context, CGRectMake(0, 0, width, height), imgRef);16 unsigned char *bitmapData = CGBitmapContextGetData (context);17 18 //这里把BitmapData进行马赛克转换,就是用一个点的颜色填充一个level*level的正方形19 unsigned char pixel[kPixelChannelCount] = { 0};20 NSUInteger index,preIndex;21 for (NSUInteger i = 0; i < height - 1 ; i++) {22 for (NSUInteger j = 0; j < width - 1; j++) {23 index = i * width + j;24 if (i % level == 0) {25 if (j % level == 0) {26 memcpy(pixel, bitmapData + kPixelChannelCount*index, kPixelChannelCount);27 }else{28 memcpy(bitmapData + kPixelChannelCount*index, pixel, kPixelChannelCount);29 }30 } else {31 preIndex = (i-1)*width +j;32 memcpy(bitmapData + kPixelChannelCount*index, bitmapData + kPixelChannelCount*preIndex, kPixelChannelCount);33 }34 }35 }36 37 NSInteger dataLength = width*height* kPixelChannelCount;38 CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmapData, dataLength, NULL);39 //创建要输出的图像40 CGImageRef mosaicImageRef = CGImageCreate(width, height,41 kBitsPerComponent,42 kBitsPerPixel,43 width*kPixelChannelCount ,44 colorSpace,45 kCGImageAlphaPremultipliedLast,46 provider,47 NULL, NO,48 kCGRenderingIntentDefault);49 CGContextRef outputContext = CGBitmapContextCreate(nil,50 width,51 height,52 kBitsPerComponent,53 width*kPixelChannelCount,54 colorSpace,55 kCGImageAlphaPremultipliedLast);56 CGContextDrawImage(outputContext, CGRectMake(0.0f, 0.0f, width, height), mosaicImageRef);57 CGImageRef resultImageRef = CGBitmapContextCreateImage(outputContext);58 UIImage *resultImage = nil;59 if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {60 float scale = [[UIScreen mainScreen] scale];61 resultImage = [UIImage imageWithCGImage:resultImageRef scale:scale orientation:UIImageOrientationUp];62 } else {63 resultImage = [UIImage imageWithCGImage:resultImageRef];64 }65 //释放66 if(resultImageRef){67 CFRelease(resultImageRef);68 }69 if(mosaicImageRef){70 CFRelease(mosaicImageRef);71 }72 if(colorSpace){73 CGColorSpaceRelease(colorSpace);74 }75 if(provider){76 CGDataProviderRelease(provider);77 }78 if(context){79 CGContextRelease(context);80 }81 if(outputContext){82 CGContextRelease(outputContext);83 }84 85 return resultImage;86 }
demo详见我的github<>