1、马赛克算法原理
把某一点的色值填充周围的区域,这样看起来会有原图的轮廓,又不会完全看不清
2、算法实现,参考:http://www.cnblogs.com/vicstudio/p/3358358.html
+(UIImage *)mosaicImage:(UIImage *)sourceImage mosaicLevel:(NSUInteger)level{
//1、这一部分是为了把原始图片转成位图,位图再转成可操作的数据
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();//颜色通道
CGImageRef imageRef = sourceImage.CGImage;//位图
CGFloat width = CGImageGetWidth(imageRef);//位图宽
CGFloat height = CGImageGetHeight(imageRef);//位图高
CGContextRef context = CGBitmapContextCreate(nil, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);//生成上下文
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), imageRef);//绘制图片到上下文中
unsigned char *bitmapData = CGBitmapContextGetData(context);//获取位图的数据
//2、这一部分是往右往下填充色值
NSUInteger index,preIndex;
unsigned char pixel[4] = {0};
for (int i = 0; i < height; i++) {//表示高,也可以说是行
for (int j = 0; j < width; j++) {//表示宽,也可以说是列
index = i * width + j;
if (i % level == 0) {
if (j % level == 0) {
//把当前的色值数据保存一份,开始为i=0,j=0,所以一开始会保留一份
memcpy(pixel, bitmapData + index * 4, 4);
}else{
//把上一次保留的色值数据填充到当前的内存区域,这样就起到把前面数据往后挪的作用,也是往右填充
memcpy(bitmapData +index * 4, pixel, 4);
}
}else{
//这里是把上一行的往下填充
preIndex = (i - 1) * width + j;
memcpy(bitmapData + index * 4, bitmapData + preIndex * 4, 4);
}
}
}
//把数据转回位图,再从位图转回UIImage
NSUInteger dataLength = width * height * 4;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmapData, dataLength, NULL);
CGImageRef mosaicImageRef = CGImageCreate(width, height,
8,
32,
width*4 ,
colorSpace,
kCGBitmapByteOrderDefault,
provider,
NULL, NO,
kCGRenderingIntentDefault);
CGContextRef outputContext = CGBitmapContextCreate(nil,
width,
height,
8,
width*4,
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];
}
CFRelease(resultImageRef);
CFRelease(mosaicImageRef);
CFRelease(colorSpace);
CFRelease(provider);
CFRelease(context);
CFRelease(outputContext);
return resultImage;
}
- (void)initView{
UIImage *img = [UIImage imageNamed:@"cat.jpg"];
UIImage *newImg = [[self class] mosaicImage:img mosaicLevel:20];
}
原图.png
效果图.png
3、demo地址:https://github.com/lihxCode/mosaicImage/tree/master
网友评论