使用Quartz 2D 可以对图片进行裁剪,简单的可以裁剪一个矩形,复杂的可以根据CGPath实现裁剪,也可以使用UIBezierPath进行裁剪,也可以使用一个UIImage做为mask进行裁剪。

对于如下图片,不使用裁剪时,显示全部内容


使用CGContextClipToRect裁剪矩形,




[cpp] ​​view plain​ ​​​copy​



  1. UIImage* imageSrc = [UIImage imageNamed:@"island.png"];  
  2.     CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();  
  3.     CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);  
  4.     CGContextClipToRect(contextRef, CGRectMake(30, 100, 200, 200));  
  5.     CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);  
  6.     CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);  
  7.     UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];  
  8.     CGContextRelease(contextRef);  
  9.     CGColorSpaceRelease(colorRef);  
  10.     return imageDst;  


结果如下:



使用CGPath 设定一个区域,然后裁剪path,




[cpp] ​​view plain​ ​​​copy​



  1. UIImage* imageSrc = [UIImage imageNamed:@"island.png"];  
  2.     CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();  
  3.     CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);  
  4.     //[path addCurveToPoint:CGPointMake(120, 80) controlPoint1:CGPointMake(<#CGFloat x#>, <#CGFloat y#>) controlPoint2:<#(CGPoint)#>]  
  5.     CGMutablePathRef mutPath = CGPathCreateMutable();  
  6.     CGPathMoveToPoint(mutPath, NULL, 30, 160);  
  7.     CGPathAddLineToPoint(mutPath, NULL, 120, 80);  
  8.     CGPathAddLineToPoint(mutPath, NULL, 210, 160);  
  9.     CGPathAddLineToPoint(mutPath, NULL, 120, 280);  
  10.     CGPathCloseSubpath(mutPath);  
  11.     CGContextAddPath(contextRef, mutPath);  
  12.     CGContextClip(contextRef);  
  13.     CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);  
  14.     CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);  
  15.     UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];  
  16.     CGContextRelease(contextRef);  
  17.     CGColorSpaceRelease(colorRef);  
  18.     return imageDst;  


结果如下:



使用UIBezierPath 创建一个裁剪区域,




[cpp] ​​view plain​ ​​​copy​



  1.       
  2. UIImage* imageSrc = [UIImage imageNamed:@"island.png"];  
  3.     CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();  
  4.     CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);  
  5.     UIBezierPath* path = [UIBezierPath bezierPath];  
  6.     [path moveToPoint:CGPointMake(30, 160)];  
  7. //  [path addCurveToPoint:CGPointMake(140, 80) controlPoint1:CGPointMake(60, 60) controlPoint2:CGPointMake(90, 60)];  
  8. //  [path addCurveToPoint:CGPointMake(210, 160) controlPoint1:CGPointMake(130, 90) controlPoint2:CGPointMake(160, 120)];  
  9. //  [path addCurveToPoint:CGPointMake(140, 280) controlPoint1:CGPointMake(180, 200) controlPoint2:CGPointMake(140, 160)];  
  10.     [path addQuadCurveToPoint:CGPointMake(140, 100) controlPoint:CGPointMake(80, 120)];  
  11.     [path addQuadCurveToPoint:CGPointMake(240, 180) controlPoint:CGPointMake(180, 100)];  
  12.     [path addQuadCurveToPoint:CGPointMake(140, 280) controlPoint:CGPointMake(210, 240)];  
  13.     [path addQuadCurveToPoint:CGPointMake(30, 160) controlPoint:CGPointMake(80, 260)];  
  14.     [path closePath];  
  15.     [path addClip];  
  16.       
  17.     CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);  
  18.     CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);  
  19.     UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];  
  20.     CGContextRelease(contextRef);  
  21.     CGColorSpaceRelease(colorRef);  
  22.     return imageDst;  


结果如下:



使用UIImage做为mask进行裁剪

使用 void CGContextClipToMask(CGContextRef c, CGRect rect,  CGImageRef mask) 

第一个参数表示context 指针

第二个参数表示clip到context的区域,也是mask 图片映射到context的区域

第三个参数表示mask的图片,对于裁剪区域Rect中的点是否变化取决于mask图中的alpha值,若alpha为0,则对应clip rect中的点为透明,如果alpha为1,则对应clip Rect中的点无变化。

另外CGContextClipToMask执行了类似  CGContextDrawImage 到rect区域的操作,不需要另外调用CGContextDrawImage。

例子:

下图为具有mask图片,图片中只有alpha值对于mask是有用的。






[cpp] ​​view plain​ ​​​copy​



  1. - (UIImage*)imageWithColor:(UIColor*)color maskImage:(UIImage*)maskImage  
  2. {  
  3.     UIImage* image =  maskImage;  
  4.     CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();  
  5.     CGContextRef contextRef = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, image.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);  
  6.     CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);  
  7.     CGContextClipToMask(contextRef, rect, image.CGImage);  
  8.     CGContextSetFillColorWithColor(contextRef, color.CGColor);  
  9.     CGContextFillRect(contextRef,rect);  
  10.     CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);  
  11.     UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];  
  12.     CGImageRelease(imageRef);  
  13.     CGContextRelease(contextRef);  
  14.     CGColorSpaceRelease(colorRef);  
  15.     return imageDst;  
  16. }  


在DrawRect中使用上述方法后,



[cpp] ​​view plain​ ​​​copy​



  1. - (void)drawRect:(CGRect)rect  
  2. {  
  3.     UIImage* image1 = [UIImage imageNamed:@"cloud.png"];  
  4.     [[self imageWithColor:[UIColor redColor] maskImage:image1] drawAtPoint:CGPointMake(0, 0)];  
  5.       
  6. }  



显示如下



修改maskRect区域,并为查看方便显示蓝色背景,代码如下




[cpp] ​​view plain​ ​​​copy​



  1. - (UIImage*)imageWithColor:(UIColor*)color maskImage:(UIImage*)maskImage  
  2. {  
  3.     UIImage* image =  maskImage;  
  4.     CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();  
  5.     CGContextRef contextRef = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, image.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);  
  6.   
  7.     CGContextSetFillColorWithColor(contextRef, [UIColor blueColor].CGColor);  
  8.     CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);  
  9.     CGContextFillRect(contextRef,rect);  
  10.     CGRect maskRect = CGRectMake(60, 0, image.size.width, image.size.height);  
  11.     CGContextClipToMask(contextRef, maskRect, image.CGImage);  
  12.     CGContextSetFillColorWithColor(contextRef, color.CGColor);  
  13.     CGContextFillRect(contextRef,rect);  
  14.     CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);  
  15.     UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];  
  16.     CGImageRelease(imageRef);  
  17.     CGContextRelease(contextRef);  
  18.     CGColorSpaceRelease(colorRef);  
  19.     return imageDst;  
  20. }  


向右偏移60像素,结果如下