1. 程式人生 > >修改圖片尺寸並且縮放和裁剪

修改圖片尺寸並且縮放和裁剪

直入主題

首先我需要的效果是:拍照或選取本地圖片後,能對圖片進行縮放,然後裁剪成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即可。

裁剪效果如圖: