前几天做图片上传的时候获取相册图片时可编辑的图片只能按照图片库的那种样式、比例限制性非常大,所以自己重写了一个来适应一般的头像上传(裁剪框为正方形)。
想法和思路很多参考了此篇文章http://www.cnblogs.com/liulunet/archive/2013/01/19/2866399.html
首先考虑的是裁剪框,裁剪框我是用四个view来做的,在四个角分别添加一个view,中间留一个自定义大小的裁剪框(有更好的方法可以下方留言)
<p class="p1"><pre name="code" class="objc">UIView *view1 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, (kSCREENWIDTH+kCUTWIDTH)/2, (kSCREENHEIGHT-kCUTHEIGHT)/2)]; view1.backgroundColor = [UIColor blackColor]; view1.alpha = 0.6; view1.userInteractionEnabled = NO;//对触摸事件不做出回应 [self.view addSubview:view1];
这个一个view的代码
kSCREENWIDTH、kSCREENHEIGHT、kCUTWIDTH、kCUTHEIGHT 分别为屏幕宽高和裁剪框的宽高
图片放在scrollView里面 设置scrollView的contentInset确保不会划出边界还有可以滑到图片的任何地方,另外必须对图片进行判断,尺寸不能太小达不到裁剪框的大小,scrollView的contentSize的大小根据图片的大小来确定,为了设置图片居中显示需要设置contentOffset,另外我还添加了双击放大和缩小的功能,同时记录下图片的缩放的尺寸以备正确裁剪图片的大小
<pre name="code" class="objc">//判断图片是否符合要求 - (BOOL)judgePictureSize:(UIImage *)image{ BOOL legalPicture = YES; CGSize imageSize = image.size; if(imageSize.width < kCUTWIDTH || imageSize.height <kCUTHEIGHT){ legalPicture = NO; }else{ if(imageSize.width > imageSize.height){ //宽图 _defaultScale = imageSize.height/kCUTHEIGHT; _currentScale = imageSize.height/kCUTHEIGHT; _scrollImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, imageSize.width/_currentScale, kCUTHEIGHT)]; }else{ //高图 _defaultScale = imageSize.width/kCUTWIDTH; _currentScale = imageSize.width/kCUTWIDTH; _scrollImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, kCUTWIDTH, imageSize.height/_currentScale)]; } self.scrollView.maximumZoomScale = _currentScale; self.scrollView.minimumZoomScale = 1.0; } return legalPicture; }
//添加scrollView到视图中
<pre name="code" class="objc">if(!self.scrollView){ self.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, kSCREENWIDTH, kSCREENHEIGHT)]; } self.scrollView.backgroundColor = [UIColor blackColor]; self.scrollView.delegate = self; //双击事件 UITapGestureRecognizer *doubleTap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(zoomInOrOut:)]; doubleTap.numberOfTapsRequired=2; [self.scrollView addGestureRecognizer:doubleTap]; [self.view addSubview:self.scrollView]; //self.originalPicture = [UIImage imageNamed:@"icon"]; _originalImage = self.originalPicture; if([self judgePictureSize:_originalImage]){ _scrollImageView.image = _originalImage; [self.scrollView addSubview:_scrollImageView]; //navigationController的高度为64 所以此处-64 UIEdgeInsets edgeInset = UIEdgeInsetsMake((kSCREENHEIGHT-kCUTHEIGHT)/2-64, (kSCREENWIDTH-kCUTWIDTH)/2, (kSCREENHEIGHT-kCUTHEIGHT)/2, (kSCREENWIDTH-kCUTWIDTH)/2); self.scrollView.contentInset = edgeInset; self.scrollView.contentSize = _scrollImageView.frame.size; //设置图片居中显示 self.scrollView.contentOffset = CGPointMake(self.scrollView.contentOffset.x+(_scrollImageView.frame.size.width-kCUTWIDTH)/2, self.scrollView.contentOffset.y+(_scrollImageView.frame.size.height-kCUTHEIGHT)/2); }else{ NSLog(@"图片尺寸太小了,换张大图吧!"); }
//scrollView双击缩放 -(void)zoomInOrOut:(UIGestureRecognizer*)tapGesture{ if(self.scrollView.zoomScale >= _defaultScale){ [self.scrollView setZoomScale:1.0 animated:YES]; }else{ CGPoint point=[tapGesture locationInView:self.scrollView]; [self.scrollView zoomToRect:CGRectMake(point.x-40, point.y-40, 40, 40) animated:YES]; } }
图片缩放弄好后就是裁剪图片和保存裁剪的图片了,裁剪的大小是根据图片缩放的比例、裁剪图片的位置是根据scrollView的contentOffset来的,图片放大倍数越大 裁剪的图片尺寸越小
裁剪图片并保存到沙盒
<pre name="code" class="objc">CGImageRef imageRef = _originalImage.CGImage; CGRect cutRect = CGRectMake((self.scrollView.contentOffset.x+(kSCREENWIDTH-kCUTWIDTH)/2)*_currentScale, (self.scrollView.contentOffset.y+(kSCREENHEIGHT-kCUTHEIGHT)/2)*_currentScale, kCUTWIDTH*_currentScale, kCUTHEIGHT*_currentScale); NSLog(@"%@",NSStringFromCGRect(cutRect)); CGImageRef subImageRef = CGImageCreateWithImageInRect(imageRef, cutRect); UIGraphicsBeginImageContext(cutRect.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextDrawImage(context, cutRect, subImageRef); UIImage *returnImage = [UIImage imageWithCGImage:subImageRef]; UIGraphicsEndImageContext(); [self savePicToSandbox:returnImage];//保存到沙盒中 [self dismissViewControllerAnimated:YES completion:nil];
//图片保存至沙盒 - (void)savePicToSandbox:(UIImage *)returnImage{ //获取沙盒目录 NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentPath = [path objectAtIndex:0]; //保存图片路径 NSData *imageData; if (UIImagePNGRepresentation(returnImage) == nil) { imageData = UIImageJPEGRepresentation(returnImage, 1); } else { imageData = UIImagePNGRepresentation(returnImage); } NSString *imagePath = [documentPath stringByAppendingPathComponent:@"headImg.png"]; NSFileManager *fm = [NSFileManager defaultManager]; [fm createFileAtPath:imagePath contents:imageData attributes:nil]; NSLog(@"%@",imagePath); }
到此就弄好了图片裁剪了。
另外贴上从相册中获取图片的代码
//上传头像 - (IBAction)uploadHeaderImg:(UIButton *)sender{ UIActionSheet *actSheet = [[UIActionSheet alloc]initWithTitle:@"上传头像" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"拍照" otherButtonTitles:@"相册", nil]; [actSheet showInView:self.view]; } -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex == 0){ UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init]; imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; imagePicker.allowsEditing = YES; imagePicker.delegate = self; [self presentViewController:imagePicker animated:YES completion:nil]; } if(buttonIndex == 1){ UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init]; imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; //imagePicker.allowsEditing = YES; imagePicker.delegate = self; [self presentViewController:imagePicker animated:YES completion:nil]; } } -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ if (picker.sourceType == UIImagePickerControllerSourceTypeCamera){ UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage]; UIImageWriteToSavedPhotosAlbum(originalImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } //获得原始图片并传到裁剪的视图控制器中 UIImage* image = [info objectForKey: @"UIImagePickerControllerOriginalImage"]; ImageScrollViewController *imageVC = [[ImageScrollViewController alloc]init]; imageVC.originalPicture = image; [picker pushViewController:imageVC animated:YES]; //[picker dismissViewControllerAnimated:YES completion:nil]; }
以下为实例截图,附上下载链接http://download.csdn.net/detail/u010530716/8365265