Quarzt 2D 裁剪
2015-07-16 14:22
274 查看
使用Quartz 2D 可以对图片进行裁剪,简单的可以裁剪一个矩形,复杂的可以根据CGPath实现裁剪,也可以使用UIBezierPath进行裁剪,也可以使用一个UIImage做为mask进行裁剪。
对于如下图片,不使用裁剪时,显示全部内容
使用CGContextClipToRect裁剪矩形,
[cpp] view
plaincopy
UIImage* imageSrc = [UIImage imageNamed:@"island.png"];
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
CGContextClipToRect(contextRef, CGRectMake(30, 100, 200, 200));
CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
结果如下:
使用CGPath 设定一个区域,然后裁剪path,
[cpp] view
plaincopy
UIImage* imageSrc = [UIImage imageNamed:@"island.png"];
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
//[path addCurveToPoint:CGPointMake(120, 80) controlPoint1:CGPointMake(<#CGFloat x#>, <#CGFloat y#>) controlPoint2:<#(CGPoint)#>]
CGMutablePathRef mutPath = CGPathCreateMutable();
CGPathMoveToPoint(mutPath, NULL, 30, 160);
CGPathAddLineToPoint(mutPath, NULL, 120, 80);
CGPathAddLineToPoint(mutPath, NULL, 210, 160);
CGPathAddLineToPoint(mutPath, NULL, 120, 280);
CGPathCloseSubpath(mutPath);
CGContextAddPath(contextRef, mutPath);
CGContextClip(contextRef);
CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
结果如下:
使用UIBezierPath 创建一个裁剪区域,
[cpp] view
plaincopy
UIImage* imageSrc = [UIImage imageNamed:@"island.png"];
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
UIBezierPath* path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(30, 160)];
// [path addCurveToPoint:CGPointMake(140, 80) controlPoint1:CGPointMake(60, 60) controlPoint2:CGPointMake(90, 60)];
// [path addCurveToPoint:CGPointMake(210, 160) controlPoint1:CGPointMake(130, 90) controlPoint2:CGPointMake(160, 120)];
// [path addCurveToPoint:CGPointMake(140, 280) controlPoint1:CGPointMake(180, 200) controlPoint2:CGPointMake(140, 160)];
[path addQuadCurveToPoint:CGPointMake(140, 100) controlPoint:CGPointMake(80, 120)];
[path addQuadCurveToPoint:CGPointMake(240, 180) controlPoint:CGPointMake(180, 100)];
[path addQuadCurveToPoint:CGPointMake(140, 280) controlPoint:CGPointMake(210, 240)];
[path addQuadCurveToPoint:CGPointMake(30, 160) controlPoint:CGPointMake(80, 260)];
[path closePath];
[path addClip];
CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
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
plaincopy
- (UIImage*)imageWithColor:(UIColor*)color maskImage:(UIImage*)maskImage
{
UIImage* image = maskImage;
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, image.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
CGContextClipToMask(contextRef, rect, image.CGImage);
CGContextSetFillColorWithColor(contextRef, color.CGColor);
CGContextFillRect(contextRef,rect);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
}
在DrawRect中使用上述方法后,
[cpp] view
plaincopy
- (void)drawRect:(CGRect)rect
{
UIImage* image1 = [UIImage imageNamed:@"cloud.png"];
[[self imageWithColor:[UIColor redColor] maskImage:image1] drawAtPoint:CGPointMake(0, 0)];
}
显示如下
修改maskRect区域,并为查看方便显示蓝色背景,代码如下
[cpp] view
plaincopy
- (UIImage*)imageWithColor:(UIColor*)color maskImage:(UIImage*)maskImage
{
UIImage* image = maskImage;
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, image.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
CGContextSetFillColorWithColor(contextRef, [UIColor blueColor].CGColor);
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
CGContextFillRect(contextRef,rect);
CGRect maskRect = CGRectMake(60, 0, image.size.width, image.size.height);
CGContextClipToMask(contextRef, maskRect, image.CGImage);
CGContextSetFillColorWithColor(contextRef, color.CGColor);
CGContextFillRect(contextRef,rect);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
}
向右偏移60像素,结果如下
对于如下图片,不使用裁剪时,显示全部内容
使用CGContextClipToRect裁剪矩形,
[cpp] view
plaincopy
UIImage* imageSrc = [UIImage imageNamed:@"island.png"];
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
CGContextClipToRect(contextRef, CGRectMake(30, 100, 200, 200));
CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
结果如下:
使用CGPath 设定一个区域,然后裁剪path,
[cpp] view
plaincopy
UIImage* imageSrc = [UIImage imageNamed:@"island.png"];
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
//[path addCurveToPoint:CGPointMake(120, 80) controlPoint1:CGPointMake(<#CGFloat x#>, <#CGFloat y#>) controlPoint2:<#(CGPoint)#>]
CGMutablePathRef mutPath = CGPathCreateMutable();
CGPathMoveToPoint(mutPath, NULL, 30, 160);
CGPathAddLineToPoint(mutPath, NULL, 120, 80);
CGPathAddLineToPoint(mutPath, NULL, 210, 160);
CGPathAddLineToPoint(mutPath, NULL, 120, 280);
CGPathCloseSubpath(mutPath);
CGContextAddPath(contextRef, mutPath);
CGContextClip(contextRef);
CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
结果如下:
使用UIBezierPath 创建一个裁剪区域,
[cpp] view
plaincopy
UIImage* imageSrc = [UIImage imageNamed:@"island.png"];
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, imageSrc.size.width, imageSrc.size.height, 8, imageSrc.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
UIBezierPath* path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(30, 160)];
// [path addCurveToPoint:CGPointMake(140, 80) controlPoint1:CGPointMake(60, 60) controlPoint2:CGPointMake(90, 60)];
// [path addCurveToPoint:CGPointMake(210, 160) controlPoint1:CGPointMake(130, 90) controlPoint2:CGPointMake(160, 120)];
// [path addCurveToPoint:CGPointMake(140, 280) controlPoint1:CGPointMake(180, 200) controlPoint2:CGPointMake(140, 160)];
[path addQuadCurveToPoint:CGPointMake(140, 100) controlPoint:CGPointMake(80, 120)];
[path addQuadCurveToPoint:CGPointMake(240, 180) controlPoint:CGPointMake(180, 100)];
[path addQuadCurveToPoint:CGPointMake(140, 280) controlPoint:CGPointMake(210, 240)];
[path addQuadCurveToPoint:CGPointMake(30, 160) controlPoint:CGPointMake(80, 260)];
[path closePath];
[path addClip];
CGContextDrawImage(contextRef, CGRectMake(0, 0, imageSrc.size.width, imageSrc.size.height), imageSrc.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
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
plaincopy
- (UIImage*)imageWithColor:(UIColor*)color maskImage:(UIImage*)maskImage
{
UIImage* image = maskImage;
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, image.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
CGContextClipToMask(contextRef, rect, image.CGImage);
CGContextSetFillColorWithColor(contextRef, color.CGColor);
CGContextFillRect(contextRef,rect);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
}
在DrawRect中使用上述方法后,
[cpp] view
plaincopy
- (void)drawRect:(CGRect)rect
{
UIImage* image1 = [UIImage imageNamed:@"cloud.png"];
[[self imageWithColor:[UIColor redColor] maskImage:image1] drawAtPoint:CGPointMake(0, 0)];
}
显示如下
修改maskRect区域,并为查看方便显示蓝色背景,代码如下
[cpp] view
plaincopy
- (UIImage*)imageWithColor:(UIColor*)color maskImage:(UIImage*)maskImage
{
UIImage* image = maskImage;
CGColorSpaceRef colorRef = CGColorSpaceCreateDeviceRGB();
CGContextRef contextRef = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, image.size.width*4, colorRef, kCGImageAlphaPremultipliedFirst);
CGContextSetFillColorWithColor(contextRef, [UIColor blueColor].CGColor);
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
CGContextFillRect(contextRef,rect);
CGRect maskRect = CGRectMake(60, 0, image.size.width, image.size.height);
CGContextClipToMask(contextRef, maskRect, image.CGImage);
CGContextSetFillColorWithColor(contextRef, color.CGColor);
CGContextFillRect(contextRef,rect);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
UIImage* imageDst = [UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorRef);
return imageDst;
}
向右偏移60像素,结果如下
相关文章推荐
- 在mysql 中两种锁定问题
- STC12C5A60S2单片机 串口调试
- GITpull 和git fetch的区别
- APP源码分享-你最美源码
- Objective-C 属性特性详解
- TypeError: 'str' does not support the buffer interface
- 18.中介者模式(Mediator Pattern)
- 斐波那契数列非递归算法(fibonacci)
- HDU 1028 Ignatius and the Princess III
- javassist学习三
- POJ 2418 Hardwood Species(STL在map应用)
- 弦截法求方程根
- Android NDK开发指南(一) Application.mk文件
- 解决VirtualBox下安装虚拟机(Ubuntu)出错(不能为虚拟电脑Ubuntu打开一个新的任务)的问题
- 学习网站
- 【记】IE下input标签中的padding-left和padding-right
- AndroidStudio百度地图开发之显示地图
- ddmlib: 您的主机中的软件中止了一个已建立的连接
- 宝宝菜谱----焖饭
- C/C++字符串函数之复制函数