高斯模糊-虚化的实现方式

1.高斯模糊


3
4
5
6
7
8
9
10
11
12
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@ "1.png" ]];
// create gaussian blur filter
CIFilter *filter = [CIFilter filterWithName:@ "CIGaussianBlur" ];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat: 10.0 ] forKey:@ "inputRadius" ];
// blur image
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage = [context createCGImage:result fromRect:[result extent]];
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
self.mainImageView.image = image;


2.



About Bitmap Images and Image Masks
  bitmap image是一系列的像素,这些像素中的每一个代表了图片中的一个点。bitmap image可以是JPEG TIFF PNG,GIF,ICO,GMP,CUR等格式。
  image mask是一个用于表征哪个部分需要画出。image mask就像是用于表征色彩放在页面的哪一部分(where to place color on the page.)
Creating Images
  创建CGImageRef类型的对象的函数有很多:
  1、CGImageCreate:
  2、CGImageSourceCreateImageAtIndex:与CGImageSourceCreateWithURL连用
  3、CGImageSourceCreateThumbnilAtIndex:与上同
  4、CGBitmapContextCreateImage:获取被画在context中的图形,构成一个图片
  5、CGImageCreateWithImageInRect:截取小图片(规则截取)
Masking Images
  mask技术通过控制另一个图片的那一部分被显示,产生出有意思的效果。
  mask的方法有一下几种:
  1、通过image mask
  2、通过image
  3、通过context
  4、通过color
Masking an Image with an Image Mask
  前提要求:
      作为mask的图片,颜色的组成为黑白两色的。黑色部分最终体现为被mask图片的显示的部分,白色部分不显示。两个图片最好都是png格式的。
  步骤:
  1、创建image mask
     通过函数CGImageMaskCreate创建一个CGImageRef的数据mask
  2、通过上一步创建的mask,与另一张图片(source)结合创建一个新的图片masked
     通过函数CGImageCreateWithMask,参数为上述两个CGImageRef的图片,返回值为masked
  3、masked既是最终需要的。可以通过CGContextDrawImage画在屏幕上。也可以通过转化为NSData类型的数据data,调用[data writeToFile@"" aumatically:YES]写入一个文件。
  注意:如果想让不显示的部分真正的是透明的,需要将context所处的View的opaqe设置为NO,既是把view设置为透明。
Bitmap <wbr>image <wbr>and <wbr>image <wbr>mask

Bitmap <wbr>image <wbr>and <wbr>image <wbr>mask

Bitmap <wbr>image <wbr>and <wbr>image <wbr>mask
如上面三幅图所示:分别为原图片(source),提供mask的图片(mask),结果(masked)。
  代码:
  -(CGImageRef) CopyImageAndAddAlphaChannel :(CGImageRef) sourceImage
{
    CGImageRef retVal = NULL;
    size_t width = CGImageGetWidth(sourceImage);
    size_t height = CGImageGetHeight(sourceImage);
   
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
   
    CGContextRef offscreenContext = CGBitmapContextCreate(NULL, width, height,
                                                          8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
   
    if (offscreenContext != NULL) {
        CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), sourceImage);
       
        retVal = CGBitmapContextCreateImage(offscreenContext);
        CGContextRelease(offscreenContext);
    }
   
    CGColorSpaceRelease(colorSpace);
    return retVal;
}

- (UIImage*)maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
    CGImageRef maskRef = maskImage.CGImage;
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);
   
    CGImageRef sourceImage = [image CGImage];
    CGImageRef imageWithAlpha = sourceImage;
    //add alpha channel for images that don’t have one (ie GIF, JPEG, etc…)
    //this however has a computational cost
    if (CGImageGetAlphaInfo(sourceImage) == kCGImageAlphaNone) {
        imageWithAlpha = [self CopyImageAndAddAlphaChannel :sourceImage];
    }
   
    CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);
    CGImageRelease(mask);
   
    //release imageWithAlpha if it was created by CopyImageAndAddAlphaChannel
    if (sourceImage != imageWithAlpha) {
        CGImageRelease(imageWithAlpha);
    }
   
    UIImage* retImage = [UIImage imageWithCGImage:masked];
    CGImageRelease(masked);   
    return retImage;
}
  希望大家注意下CopyImageAndAddAlphaChannel函数中的,CGBitmapContextCreate函数的最后一个参数,这里我用的是kCGImageAlphaPremultipliedLast。
Masking an Image with an Image
 
 通过image进行mask,这一部分我没有用代码实际的去尝试,大家有兴趣可以试试。
Masking an image with Color
  该项技术主要是想通过提供一个color的阈值,对图片进行mask。达到的效果如下图所示:
Bitmap <wbr>image <wbr>and <wbr>image <wbr>mask
  实现这种效果的方法是CGImageCreateWithMaskingColors,参数为CGImageRef和float的color数组。
  针对这个color数组格式如下:{min[1],max[1],min[2],max[2],min[3],max[3]···min[n],max[n]},其中的n表示的是当前的color space的元素的个数,比如当前采用rgb三原色,则n=3。
  该方法实现的过程大致表述如下:对图片的任何一个像素点,他的color是c[1],c[2],c[3],c[n],如果满足min[i]< c[i] <max[i]对所有的0到n成立,则这个像素点不被显示。
  特别注意:
  1、原图片(source)的格式应该是没有alpha通道的,如果提供的是png,由于png貌似都是有alpha的,需要先将png转化为jpeg,之后再通过maskwithcolor实现mask
  2、color数组的格式和取值范围是0到255
代码:
- (UIImage *)maskImage:(UIImage *)image withColor:(float *)color
{
    CGImageRef sourceImage = image.CGImage;
   
    CGImageAlphaInfo info = CGImageGetAlphaInfo(sourceImage);   
    if (info != kCGImageAlphaNone) {
        NSData *buffer = UIImageJPEGRepresentation(image, 1);
        UIImage *newImage = [UIImage imageWithData:buffer];
        sourceImage = newImage.CGImage;
    }
   
    CGImageRef masked = CGImageCreateWithMaskingColors(sourceImage, color);
    UIImage *retImage = [UIImage imageWithCGImage:masked];  
    CGImageRelease(masked);
    return retImage;
}
 这部分我是这样实现的,在view中实现touch,在touch begain的时候获取该点的rgb,touch end的时候获取该点的rgb,之后clip to colors。效果如下:
Bitmap <wbr>image <wbr>and <wbr>image <wbr>mask

Masking an Image by Clipping the Context
  这种技术的手段是通过将context clip,这样所有画在这个context的图片,就相应的被mask了。
  采用的函数是CGContextClipToMask,这里还是需要给它提供一个通过CGImageMaskCreate创建的mask。将source图片通过CGContextDrawImage之后,通过CGBitmapContextCreateImage获取对应的masked。
  当然这里还可以通过与path的知识结合,通过调用CGContextClip,实现画哪里clip哪里。
代码:
- (void)clipContext:(CGContextRef)context withMask:(UIImage *)maskImage
{
    CGImageRef maskRef = maskImage.CGImage;
    CGImageRef masked = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);
   
    CGContextClipToMask(context, CGRectMake(0, 0, 768, 1024), masked);
    CGImageRelease(masked);
}
针对第二种clip path的,我实现的效果:(左边是source,右边是masked)
Bitmap <wbr>image <wbr>and <wbr>image <wbr>mask
另外,最后指出一点,UIImage的drawRect函数仅仅在第一次加载的时候被调用一次,之后如果在view里面添加了东西,需要刷新的时候需要调用setNeedsDisplay函数。

3
4
5
6
7
8
9
10
11
12
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@ "1.png" ]];
// create gaussian blur filter
CIFilter *filter = [CIFilter filterWithName:@ "CIGaussianBlur" ];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat: 10.0 ] forKey:@ "inputRadius" ];
// blur image
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage = [context createCGImage:result fromRect:[result extent]];
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
self.mainImageView.image = image;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值