在一些情况下需要对图片进行缩放操作.比如使用iPhone6 Plus拍照得到的将是一张2448x3264的图片,这么大分辨率的图片已经远远超过了手机显示屏的分辨率了,如果直接加载到内存会占用很大的空间,这显然是一种浪费.这个时候就需要等比例缩放图片以减小图片分辨率.一般情况下,即时聊天页面用户发送的图片都会经过分辨率压缩和体积压缩后才会上传到服务器.
由于图片的大小和目标大小比例可能不一致,因此等比例缩放图片到目标尺寸有两种填充方式:
1.等比例填满目标大小,图片可能发生裁剪
两种情况:
1.图片与目标大小宽高比一致.
由于与目标大小宽高比一致,图片缩放后会恰好填满整个目标大小,图片不会发生裁剪.
2.图片与目标大小宽高比不一致.
由于与目标大小宽高比不一致,图片缩放后会超出目标大小,因此图片会发生裁剪.
这里又分为两种情况:
prate < drate,图片会在y轴发生裁剪.
prate > drate,图片会在x轴发生裁剪.
如下图所示:
108*108
(CGSize) targetSize = (width = 81, height = 162)
(CGRect) rect = (origin = (x = -40.5, y = 0), size = (width = 162, height = 162))
2.等比例适应目标大小,图片可能会有空白部分
两种情况:
1.图片与目标大小宽高比一致.
由于与目标大小宽高比一致,图片缩放后会恰好填满整个目标大小,图片不会有空白部分.
2.图片与目标大小宽高比不一致.
由于与目标大小宽高比不一致,图片缩放后会有空白部分.
这里又分为两种情况:
prate < drate,图片会在x轴产生空白.
prate > drate,图片会在y轴产生空白.
如下图所示:
108*108
(CGSize) targetSize = (width = 81, height = 162)
(CGRect) rect = (origin = (x = 0, y = 40.5), size = (width = 81, height = 81))
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| // MARK: - 缩放图片
typedef NS_ENUM(NSUInteger, ZAEImageScaleMode) { ZAEImageScaleModeFill = 0, //填满 ZAEImageScaleModeAspectFit = 1, //等比例适应 ZAEImageScaleModeAspectFill = 2 //等比例填满 };
/** 缩放图片.返回的图片的scale为屏幕scale.
@param image 原始图片 @param targetSize 目标尺寸 @param scaleMode 缩放模式 @return 缩放后的图片. */ + (UIImage *)za_resizeImage:(UIImage *)image targetSize:(CGSize)targetSize scaleMode:(ZAEImageScaleMode)scaleMode;
/** 缩放图片.
@param image 原始图片 @param targetSize 目标尺寸 @param scale 目标scale.[1,屏幕scale] @param scaleMode 缩放模式 @return 缩放后的图片. */ + (UIImage *)za_resizeImage:(UIImage *)image targetSize:(CGSize)targetSize scale:(CGFloat)scale scaleMode:(ZAEImageScaleMode)scaleMode;
...
+ (UIImage *)za_resizeImage:(UIImage *)image targetSize:(CGSize)targetSize scaleMode:(ZAEImageScaleMode)scaleMode { return [UIImage za_resizeImage:image targetSize:targetSize scale:[UIScreen mainScreen].scale scaleMode:scaleMode]; }
+ (UIImage *)za_resizeImage:(UIImage *)image targetSize:(CGSize)targetSize scale:(CGFloat)scale scaleMode:(ZAEImageScaleMode)scaleMode { if (targetSize.width <= 0 || targetSize.height <= 0 || image == nil) return nil; if (scale < 1) { scale = 1; } if (scale > [UIScreen mainScreen].scale) { scale = [UIScreen mainScreen].scale; } UIGraphicsBeginImageContextWithOptions(targetSize, NO, scale); CGRect rect = [self CGRectFitWithRect:CGRectMake(0, 0, targetSize.width, targetSize.height) size:image.size scaleMode:scaleMode]; [image drawInRect:rect]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); if(newImage == nil) { NSLog(@"scale image fail"); } UIGraphicsEndImageContext(); return newImage; }
+ (CGRect)CGRectFitWithRect:(CGRect)rect size:(CGSize)size scaleMode:(ZAEImageScaleMode)scaleMode { rect = CGRectStandardize(rect); size.width = size.width < 0 ? -size.width : size.width; size.height = size.height < 0 ? -size.height : size.height; CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); switch (scaleMode) { case ZAEImageScaleModeAspectFit: case ZAEImageScaleModeAspectFill: { if (rect.size.width < 0.01 || rect.size.height < 0.01 || size.width < 0.01 || size.height < 0.01) { rect.origin = center; rect.size = CGSizeZero; } else { CGFloat scale; if (scaleMode == ZAEImageScaleModeAspectFit) { if (size.width / size.height < rect.size.width / rect.size.height) { //图片宽不够 scale = rect.size.height / size.height; //拉伸高 } else { scale = rect.size.width / size.width; } } else { if (size.width / size.height < rect.size.width / rect.size.height) { //图片宽不够 scale = rect.size.width / size.width; //拉伸宽 } else { scale = rect.size.height / size.height; } } size.width *= scale; size.height *= scale; rect.size = size; rect.origin = CGPointMake(center.x - size.width * 0.5, center.y - size.height * 0.5); } } break; case ZAEImageScaleModeFill: default: { rect = rect; } } return rect; }
|