修改圖片尺寸並且縮放和裁剪
阿新 • • 發佈:2019-01-27
直入主題
首先我需要的效果是:拍照或選取本地圖片後,能對圖片進行縮放,然後裁剪成4:3比例的尺寸大小。
所以首先在 UIImagePickerController的didFinishPickingMediaWithInfo:方法裡獲取到原圖,直接上程式碼
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info { //原圖 UIImage *OriginalImage = info[UIImagePickerControllerOriginalImage]; //圖片原始尺寸(因為原圖尺寸很大,所以我修改了下尺寸在做處理) CGSize originalSize = OriginalImage.size; //寬高比 CGFloat scale = originalSize.width / originalSize.height; //新的尺寸 CGFloat width; CGFloat height; if (scale >= 1) {//如果圖片寬 >= 高 //SCREEN_WIDTH是螢幕寬度的巨集 height = SCREEN_WIDTH / 4 * 3; // 4:3 比例 width = height * scale; } else { //寬 < 高 width = SCREEN_HEIGHT * scale; height = SCREEN_HEIGHT; } //修改尺寸後的圖片 UIImage *newImage = [UIImage originImage:OriginalImage scaleToSize:CGSizeMake(width, height)]; //獲取到已經修改好尺寸的圖片後,需要對圖片進行編輯,自定義一個控制器,在裡面進行縮放,裁剪處理 } /** 按比例改變圖片尺寸 */ + (UIImage*)originImage:(UIImage *)image scaleToSize:(CGSize)size { UIGraphicsBeginImageContext(size); //所需要的圖片尺寸 //這裡一定要傳裝置的解析度,不然圖片會變模糊 UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); //繪製改變大小的圖片 [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; //從當前context中建立一個改變大小後的圖片 UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); //使當前的context出堆疊 UIGraphicsEndImageContext(); return scaledImage; //返回的就是已經改變的圖片 }
現在我們已經拿到改好尺寸後的圖片了,下面要對圖片進行縮放
為了使圖片能夠縮放,我建立了一個scrollView把圖片放上去
這兩個屬性控制縮放的最大和最小比例
scrollView.maximumZoomScale = 2.0;
scrollView.minimumZoomScale = 1.0
在代理中設定相關方法
#pragma mark - <UIScrollViewDelegate> //設定可縮放檢視 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.imageView; } //縮放時 - (void)scrollViewDidZoom:(UIScrollView *)scrollView { //動態修改contentSize scrollView.contentSize = CGSizeMake(self.imageView.width, SCREEN_HEIGHT + self.imageView.height - self.borderLine.height); } //結束縮放時 - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { //用此時縮放尺寸的圖片來裁剪 self.image = [UIImage originImage:self.image scaleToSize:self.imageView.size]; //設定當前的縮放比例(這個比例在裁剪圖片時會用到) //ViewDidLoad時,把scrollView的縮放比例初始化為1倍 self.scrollScale = scale; }
然後還需要一個框用來裁剪圖片,大概這個樣子
為了讓圖片能完全出現在這個框中,還需要根據圖片的大小設定scrollView的contentSize
// 高度的size = 螢幕的高度加上多出 imageView的圖片的高度,圖片多出多少,size就增加多少(這裡imageView的高度減去裁剪框的高度就是多出的圖片的高度) //borderLine是我的裁剪框 scrollView.contentSize = CGSizeMake(self.imageView.width, SCREEN_HEIGHT + self.imageView.height - self.borderLine.height); //讓imageView居中顯示在裁剪框內 imgView.centerX = scrollView.contentSize.width * 0.5; imgView.centerY = scrollView.contentSize.height * 0.5; //進入時,顯示圖片中心位置 scrollView.contentOffset = CGPointMake((self.imageView.width - borderLine.width) * 0.5, (self.imageView.height - borderLine.height) * 0.5);
這些都設定好之後,就可以開始裁剪圖片了,還是直接上程式碼
//裁剪圖片
- (UIImage *)cropImageFromOriginalImage:(UIImage *)originalImage {
//需要裁剪的尺寸
CGSize cropImageSize = self.borderLine.size;
//螢幕解析度
CGFloat scale = [UIScreen mainScreen].scale;
//座標系轉換(把裁剪框放到imageView上)
CGRect rect = [self.view convertRect:self.borderLine.frame toView:self.imageView];
//裁剪框的位置乘上當前縮放比例
CGFloat y = rect.origin.y;
y = y * self.scrollScale;
rect.origin.y = y;
CGFloat x = rect.origin.x;
x = x * self.scrollScale;
rect.origin.x = x;
//設定裁剪的區域,在原圖片的位置上,均乘上螢幕解析度
CGRect cropImageRect = CGRectMake(rect.origin.x * scale, rect.origin.y * scale, self.borderLine.width * scale, self.borderLine.height * scale);
//裁剪
CGImageRef imageRef = originalImage.CGImage;
CGImageRef cropImageRef = CGImageCreateWithImageInRect(imageRef, cropImageRect);
UIGraphicsBeginImageContext(cropImageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, cropImageRect, cropImageRef);
UIImage *cropImage = [UIImage imageWithCGImage:cropImageRef];
CGImageRelease(cropImageRef);//需要手動釋放,不然會記憶體洩露
UIGraphicsEndImageContext();
//返回裁剪的影象
return cropImage;
}
裁剪方法很簡單,就是上面這段,這裡只是為了實現功能,沒有把程式碼精簡重構。可以把需要裁剪的rect提到方法外去,使用的時候直接傳圖片和rect即可。
裁剪效果如圖: