項目中常會遇到,上傳圖片的操做,因爲iPhone手機直接拍照的圖片每每比較大,通常3-4M,若是直接上傳不作處理會浪費用戶不少流量,再者有不少場景並不須要高清圖片,因此在上傳圖片前對圖片進行壓縮,是頗有必要的。服務器
1.OC中的UIKit中提供了現成的壓縮函數 UIImageJPEGRepresentation(UIImage * __nonnull image, CGFloat compressionQuality) ,但壓縮比率只能是0.1到0.9,若是圖片過大,仍是沒法達到咱們想要的效果。函數
2.對於大圖片(10M以上),咱們能夠先對圖片進行裁剪,而後再壓縮。這個方法能大大壓縮圖片的大小。以個人項目中需求爲例,需求是:無論多大圖片,都要壓縮至50kb左右才能夠上傳到服務器,並且像素不能過分失真。this
1 + (NSData *)compressWithOrgImg:(UIImage *)img 2 { 3 4 NSData *imageData = UIImageJPEGRepresentation(img, 1); 5 float length = imageData.length; 6 length = length/1024; 7 NSLog(@"壓縮前的大小:%fKB",length); 8 // 裁剪比例 9 CGFloat cout = 0.5; 10 11 // 壓縮比例 12 CGFloat imgCout = 0.1; 13 if(length > 25000){ // 25M以上的圖片 14 cout = 0.1; 15 imgCout = 0; 16 }else if(length > 10000){ // 10M以上的圖片 17 cout = 0.2; 18 imgCout = 0; 19 }else if (length > 5000) { // 5M以上的圖片 20 cout = 0.3; 21 imgCout = 0; 22 }else if (length > 1500) { // 若是原圖大於1.5M就換一個壓縮級別 23 cout = 0.7; 24 imgCout = 0.1; 25 }else if (length > 1000) { 26 cout = 0.8; 27 imgCout = 0.2; 28 }else if (length > 500) { 29 cout = 0.8; 30 imgCout = 0.3; 31 }else if (length >100){ // 小於500k的不用裁剪 32 33 imageData = UIImageJPEGRepresentation(img, 50 / imageData.length); 34 float length = imageData.length; 35 length = length/1024; 36 NSLog(@"壓縮後的大小:%fKB",length); 37 return imageData; 38 }else{ 39 40 imageData = UIImageJPEGRepresentation(img, 0.5); 41 float length = imageData.length; 42 length = length/1024; 43 NSLog(@"壓縮後的大小:%fKB",length); 44 return imageData; 45 } 46 47 48 // 按裁剪比例裁剪 49 UIImage *compressImage = [img imageByScalingAndCroppingForSize:CGSizeMake(img.size.width * cout, img.size.height *cout)]; 50 51 52 // 那壓縮比例壓縮 53 imageData = UIImageJPEGRepresentation(compressImage, imgCout); 54 55 length= imageData.length / 1024; 56 NSLog(@"裁剪比例:%f,壓縮比例:%f,壓縮後的大小:%fKB",cout,imgCout,length); 57 return imageData; 58 }
1 // 裁剪 2 - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize 3 { 4 UIImage *sourceImage = self; 5 UIImage *newImage = nil; 6 CGSize imageSize = sourceImage.size; 7 CGFloat width = imageSize.width; 8 CGFloat height = imageSize.height; 9 CGFloat targetWidth = targetSize.width; 10 CGFloat targetHeight = targetSize.height; 11 CGFloat scaleFactor = 0.0; 12 CGFloat scaledWidth = targetWidth; 13 CGFloat scaledHeight = targetHeight; 14 CGPoint thumbnailPoint = CGPointMake(0.0,0.0); 15 16 if (CGSizeEqualToSize(imageSize, targetSize) == NO) 17 { 18 CGFloat widthFactor = targetWidth / width; 19 CGFloat heightFactor = targetHeight / height; 20 21 if (widthFactor > heightFactor) 22 scaleFactor = widthFactor; // scale to fit height 23 else 24 scaleFactor = heightFactor; // scale to fit width 25 scaledWidth= width * scaleFactor; 26 scaledHeight = height * scaleFactor; 27 28 // center the image 29 if (widthFactor > heightFactor) 30 { 31 thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 32 } 33 else if (widthFactor < heightFactor) 34 { 35 thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; 36 } 37 } 38 39 UIGraphicsBeginImageContext(targetSize); // this will crop 40 41 CGRect thumbnailRect = CGRectZero; 42 thumbnailRect.origin = thumbnailPoint; 43 thumbnailRect.size.width= scaledWidth; 44 thumbnailRect.size.height = scaledHeight; 45 46 [sourceImage drawInRect:thumbnailRect]; 47 48 newImage = UIGraphicsGetImageFromCurrentImageContext(); 49 if(newImage == nil) 50 NSLog(@"could not scale image"); 51 52 //pop the context to get back to the default 53 UIGraphicsEndImageContext(); 54 return newImage; 55 }
代碼中針對不一樣大小圖片,給出了不一樣的壓縮比率,以保證壓縮後的圖片大小都在50k左右。此處的「裁剪」是將圖片的寬高等比例縮小到指定的比率spa