转自:http://blog.sina.com.cn/s/blog_6084f58801013n34.html
现在打算做一个拼图游戏,游戏引擎用cocos2d。先说一下设计要求,支持从相册或相机所拍照片中导入图片,导入的图片往往不符合我们的要求,这时就需要我们进行图片的裁剪
如图所示,当用户对图片进行缩放,移动变换后,最终把方框中的图片裁剪出来作为拼图游戏中的图片素材。先说一下前部中空四周半透明UIImage的绘制方式,直接上代码:
// draw the front image
- (UIImageView *)frontView{
CGSize winSize=CGSizeMake(1024, 768);
UIImageView * fView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, winSize.width, winSize.height)];
CGColorSpaceRefcolorSpace = CGColorSpaceCreateDeviceRGB();
// 1. create the context, reverse it upside down; after the translate, origin is at top-left corner
CGContextRef context = CGBitmapContextCreate(NULL, winSize.width, winSize.height, 8, 4 * winSize.width, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextSaveGState(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, winSize.width, 0);
CGContextAddLineToPoint(context, winSize.width, winSize.height);
CGContextAddLineToPoint(context, 0, winSize.height);
CGContextAddLineToPoint(context, 0, 0);
CGContextMoveToPoint(context, winSize.width*0.2, winSize.height*0.2);
CGContextAddLineToPoint(context, winSize.width*0.8, winSize.height*0.2);
CGContextAddLineToPoint(context, winSize.width*0.8, winSize.height*0.8);
CGContextAddLineToPoint(context, winSize.width*0.2, winSize.height*0.8);
CGContextAddLineToPoint(context, winSize.width*0.2, winSize.height*0.2);
CGContextClosePath(context);
CGContextSetRGBFillColor(context, 0.6,0.6, 0.6, 0.6);
CGContextEOFillPath(context);
CGContextRestoreGState(context);
// get the image
CGImageRef largeImageMasked = CGBitmapContextCreateImage(context);
// 5. get only the specific region
CGImageRef imageMasked = CGImageCreateWithImageInRect(largeImageMasked, CGRectMake(0, 0, winSize.width, winSize.height));
CGImageRelease(largeImageMasked);
CGContextRelease(context);
UIImage * newImage = [UIImageimageWithCGImage:imageMasked];
CGImageRelease(imageMasked);
fView.image=newImage;
[fView sizeToFit];
return [fView autorelease];
}
这次到重点了,就是图片的裁剪。
下面为裁剪部分的代码
- (void)clipBtnClicked:(id)sender{
CGSize winSize=[[CCDirector sharedDirector] winSize];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGSize imageSize=[[_imageView image] size];
// 1. create the context, reverse it upside down; after the translate, origin is at top-left corner
CGContextRef context = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height, 8, 4 * imageSize.width, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextSaveGState(context);
CGContextDrawImage(context, CGRectMake(0,0,imageSize.width,imageSize.height),_imageView.image.CGImage);
CGContextRestoreGState(context);
//imageScale
float scale=_imageView.frame.size.width/imageSize.width;
CGSize clipSize=CGSizeMake(winSize.width*0.6/scale, winSize.height*0.6/scale);
//offset from center
CGPoint offset=ccpSub(ccp(_imageView.frame.origin.x,_imageView.frame.origin.y+_imageView.frame.size.height),ccp(winSize.width*0.2,winSize.height*0.8));
offset=ccp(-offset.x,offset.y/scale);
CGContextSaveGState(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, offset.x, offset.y);
CGContextAddLineToPoint(context, offset.x, offset.y+clipSize.height);
CGContextAddLineToPoint(context, offset.x+clipSize.width, offset.y+clipSize.height);
CGContextAddLineToPoint(context, offset.x+clipSize.width, offset.y);
CGContextAddLineToPoint(context, offset.x, offset.y);
CGContextClosePath(context);
CGContextRestoreGState(context);
CGContextSaveGState(context);
CGContextSetRGBFillColor(context, 1, 0, 0, 0.2);
CGContextFillPath(context);
CGContextRestoreGState(context);
// stroke
CGContextSetStrokeColorSpace(context, colorSpace);
CGFloat strokeColor[4] = {1.0,0,0,1.0};
CGContextSetStrokeColor(context, strokeColor);
CGContextSetLineWidth(context, 4);
CGContextStrokePath(context);
// get the image
CGImageRef largeImageMasked = CGBitmapContextCreateImage(context);
CGPoint offset2=ccpSub(ccp(_imageView.frame.origin.x,_imageView.frame.origin.y),ccp(winSize.width*0.2,winSize.height*0.2));
offset2=ccp(-offset2.x,-offset2.y/scale);
// 5. get only the specific region
CGImageRef imageMasked = CGImageCreateWithImageInRect(largeImageMasked,CGRectMake(offset2.x,offset2.y, clipSize.width, clipSize.height));
CGImageRelease(largeImageMasked);
//CGImageRef imageMasked = largeImageMasked;
CGContextRelease(context);
UIImage* newImage = [UIImage imageWithCGImage:imageMasked];
CGImageRelease(imageMasked);
// 创建一个bitmap的context
// 并把它设置成为当前正在使用的context
UIGraphicsBeginImageContext(CGSizeMake(winSize.width*0.6, winSize.height*0.6));
// 绘制改变大小的图片
[newImage drawInRect:CGRectMake(0, 0, winSize.width*0.6, winSize.height*0.6)];
// 从当前context中创建一个改变大小后的图片
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
// 使当前的context出堆栈
UIGraphicsEndImageContext();
}
最终的newImage就是你最终希望得到的图片。