前言:还是这个图片浏览的小demo,在里面实现了对单张图片的放大缩小。现在把我已知的图片缩放的各种方法记录下来,方便以后查阅,毕竟图片缩放还是经常用到的。
正文:构建图像缩略图,通常有3种形式:保持图像比例不变调整大小;裁剪部分图像来匹配可用空间;通过匹配可用空间的长度和宽度来填充图像。
一、最简单的方法[sourceImage drawInRect:newImageRect]; //sourceImage为原图,newImageRect指定了图片绘制区域
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
OK,newImage 就是你要的图。缺点:回丢失很多图片信息
_srcollView.minimumZoomScale=0.5f;//最小缩小倍数
_srcollView.maximumZoomScale=2.0f;//最大方法倍数
// return a view that will be scaled. if delegate returns nil, nothing happen - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { NSLog(@"viewForZoomingInScrollView"); for (id view in [_srcollView subviews]) { if ([view isKindOfClass:[UIImageView class]]) { return view; } } return nil; }
1 #import <Foundation/Foundation.h> 2 3 #define CGAutorelease(x) (__typeof(x))[NSMakeCollectable(x) autorelease] 4 5 #define SUPPPORTS_UNDOCUMENTED_APIS 1 6 7 @interface ImageHelper : NSObject 8 // Create image 9 + (UIImage *) imageFromView: (UIView *) theView; 10 11 // Base Image Fitting 12 + (CGSize) fitSize: (CGSize)thisSize inSize: (CGSize) aSize; 13 + (UIImage *) unrotateImage: (UIImage *) image; 14 15 + (UIImage *) image: (UIImage *) image fitInSize: (CGSize) size; // retain proportions, fit in size 16 + (UIImage *) image: (UIImage *) image fitInView: (UIView *) view; 17 18 + (UIImage *) image: (UIImage *) image centerInSize: (CGSize) size; // center, no resize 19 + (UIImage *) image: (UIImage *) image centerInView: (UIView *) view; 20 21 + (UIImage *) image: (UIImage *) image fillSize: (CGSize) size; // fill all pixels 22 + (UIImage *) image: (UIImage *) image fillView: (UIView *) view; 23 24 #if SUPPPORTS_UNDOCUMENTED_APIS 25 + (UIImage *) image: (UIImage *) image withOrientation: (UIImageOrientation) orientation; 26 #endif 27 28 //截取view部分图片 29 + (UIImage *) imageFromViewWithRect:(UIView *)theView rect:(CGRect)rect; 30 @end
1 #import "ImageHelper.h" 2 #import <QuartzCore/QuartzCore.h> 3 4 #if SUPPPORTS_UNDOCUMENTED_APIS 5 @interface UIImage (privateAPISForOrientation) 6 - (id)initWithCGImage:(struct CGImage *)fp8 imageOrientation:(int)fp12; 7 @end 8 #endif 9 10 @implementation ImageHelper 11 12 #pragma mark Create Image 13 14 // Screen shot the view 15 + (UIImage *) imageFromView: (UIView *) theView 16 { 17 UIGraphicsBeginImageContext(theView.frame.size); 18 CGContextRef context = UIGraphicsGetCurrentContext(); 19 [theView.layer renderInContext:context]; 20 UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext(); 21 UIGraphicsEndImageContext(); 22 return theImage; 23 } 24 25 #pragma mark Base Image Utility 26 + (CGSize) fitSize: (CGSize)thisSize inSize: (CGSize) aSize 27 { 28 CGFloat scale; 29 CGSize newsize = thisSize; 30 31 32 if (newsize.height && (newsize.height > aSize.height))//如果新图的高度不为0,且大于原图高度 33 { 34 scale = aSize.height / newsize.height;//比例为 原高/新高 35 newsize.width *= scale;//新图的宽度等于 = 36 newsize.height *= scale; 37 } 38 39 if (newsize.width && (newsize.width >= aSize.width)) 40 { 41 scale = aSize.width / newsize.width; 42 newsize.width *= scale; 43 newsize.height *= scale; 44 } 45 46 return newsize; 47 } 48 49 #define MIRRORED ((image.imageOrientation == UIImageOrientationUpMirrored) || (image.imageOrientation == UIImageOrientationLeftMirrored) || (image.imageOrientation == UIImageOrientationRightMirrored) || (image.imageOrientation == UIImageOrientationDownMirrored)) 50 #define ROTATED90 ((image.imageOrientation == UIImageOrientationLeft) || (image.imageOrientation == UIImageOrientationLeftMirrored) || (image.imageOrientation == UIImageOrientationRight) || (image.imageOrientation == UIImageOrientationRightMirrored)) 51 52 + (UIImage *) doUnrotateImage: (UIImage *) image 53 { 54 CGSize size = image.size; 55 if (ROTATED90) size = CGSizeMake(image.size.height, image.size.width); 56 57 UIGraphicsBeginImageContext(size); 58 CGContextRef context = UIGraphicsGetCurrentContext(); 59 CGAffineTransform transform = CGAffineTransformIdentity; 60 61 // Rotate as needed 62 switch(image.imageOrientation) 63 { 64 case UIImageOrientationLeft: 65 case UIImageOrientationRightMirrored: 66 transform = CGAffineTransformRotate(transform, M_PI / 2.0f); 67 transform = CGAffineTransformTranslate(transform, 0.0f, -size.width); 68 size = CGSizeMake(size.height, size.width); 69 CGContextConcatCTM(context, transform); 70 break; 71 case UIImageOrientationRight: 72 case UIImageOrientationLeftMirrored: 73 transform = CGAffineTransformRotate(transform, -M_PI / 2.0f); 74 transform = CGAffineTransformTranslate(transform, -size.height, 0.0f); 75 size = CGSizeMake(size.height, size.width); 76 CGContextConcatCTM(context, transform); 77 break; 78 case UIImageOrientationDown: 79 case UIImageOrientationDownMirrored: 80 transform = CGAffineTransformRotate(transform, M_PI); 81 transform = CGAffineTransformTranslate(transform, -size.width, -size.height); 82 CGContextConcatCTM(context, transform); 83 break; 84 default: 85 break; 86 } 87 88 89 if (MIRRORED) 90 { 91 // de-mirror 92 transform = CGAffineTransformMakeTranslation(size.width, 0.0f); 93 transform = CGAffineTransformScale(transform, -1.0f, 1.0f); 94 CGContextConcatCTM(context, transform); 95 } 96 97 // Draw the image into the transformed context and return the image 98 [image drawAtPoint:CGPointMake(0.0f, 0.0f)]; 99 UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext(); 100 UIGraphicsEndImageContext(); 101 return newimg; 102 } 103 104 + (UIImage *) unrotateImage: (UIImage *) image 105 { 106 if (image.imageOrientation == UIImageOrientationUp) return image; 107 return [ImageHelper doUnrotateImage:image]; 108 } 109 110 111 112 // Proportionately resize, completely fit in view, no cropping 113 + (UIImage *) image: (UIImage *) image fitInSize: (CGSize) viewsize 114 { 115 // calculate the fitted size 116 CGSize size = [ImageHelper fitSize:image.size inSize:viewsize]; 117 118 UIGraphicsBeginImageContext(viewsize); 119 120 float dwidth = (viewsize.width - size.width) / 2.0f; 121 float dheight = (viewsize.height - size.height) / 2.0f; 122 123 CGRect rect = CGRectMake(dwidth, dheight, size.width, size.height); 124 [image drawInRect:rect]; 125 126 UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext(); 127 UIGraphicsEndImageContext(); 128 129 return newimg; 130 } 131 132 + (UIImage *) image: (UIImage *) image fitInView: (UIView *) view 133 { 134 return [self image:image fitInSize:view.frame.size]; 135 } 136 137 // No resize, may crop 138 + (UIImage *) image: (UIImage *) image centerInSize: (CGSize) viewsize 139 { 140 CGSize size = image.size; 141 142 UIGraphicsBeginImageContext(viewsize); 143 float dwidth = (viewsize.width - size.width) / 2.0f; 144 float dheight = (viewsize.height - size.height) / 2.0f; 145 146 CGRect rect = CGRectMake(dwidth, dheight, size.width, size.height); 147 [image drawInRect:rect]; 148 149 UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext(); 150 UIGraphicsEndImageContext(); 151 152 return newimg; 153 } 154 155 + (UIImage *) image: (UIImage *) image centerInView: (UIView *) view 156 { 157 return [self image:image centerInSize:view.frame.size]; 158 } 159 160 // Fill every view pixel with no black borders, resize and crop if needed 161 + (UIImage *) image: (UIImage *) image fillSize: (CGSize) viewsize 162 163 { 164 CGSize size = image.size; 165 166 CGFloat scalex = viewsize.width / size.width; 167 CGFloat scaley = viewsize.height / size.height; 168 CGFloat scale = MAX(scalex, scaley); 169 170 UIGraphicsBeginImageContext(viewsize); 171 172 CGFloat width = size.width * scale; 173 CGFloat height = size.height * scale; 174 175 float dwidth = ((viewsize.width - width) / 2.0f); 176 float dheight = ((viewsize.height - height) / 2.0f); 177 178 CGRect rect = CGRectMake(dwidth, dheight, size.width * scale, size.height * scale); 179 [image drawInRect:rect]; 180 181 UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext(); 182 UIGraphicsEndImageContext(); 183 184 return newimg; 185 } 186 187 + (UIImage *) image: (UIImage *) image fillView: (UIView *) view 188 { 189 return [self image:image fillSize:view.frame.size]; 190 } 191 192 #if SUPPPORTS_UNDOCUMENTED_APIS 193 + (UIImage *) image: (UIImage *) image withOrientation: (UIImageOrientation) orientation 194 { 195 UIImage *newimg = [[UIImage alloc] initWithCGImage:[image CGImage] imageOrientation:orientation]; 196 return [newimg autorelease]; 197 } 198 #endif 199 200 //截取view部分图片 201 + (UIImage *) imageFromViewWithRect:(UIView *)theView rect:(CGRect)rect 202 { 203 CGFloat scale = 1.0f; 204 if (UIGraphicsBeginImageContextWithOptions != NULL) 205 { 206 UIGraphicsBeginImageContextWithOptions(theView.bounds.size, NO, theView.layer.contentsScale); 207 scale = theView.layer.contentsScale; 208 } 209 else 210 { 211 UIGraphicsBeginImageContext(theView.bounds.size); 212 } 213 214 CALayer * curLayer = [theView layer]; 215 CGContextRef context = UIGraphicsGetCurrentContext(); 216 [curLayer renderInContext:context]; 217 218 UIImage * pImage = UIGraphicsGetImageFromCurrentImageContext(); 219 CGImageRef imageRef = pImage.CGImage; 220 CGRect rectSubImage = {rect.origin.x*scale,rect.origin.y*scale,rect.size.width*scale,rect.size.height*scale}; 221 CGImageRef subImageRef = CGImageCreateWithImageInRect(imageRef, rectSubImage); 222 rect.size.width *=scale; 223 rect.size.height *=scale; 224 CGSize size = rect.size; 225 UIGraphicsBeginImageContext(size); 226 CGContextRef subcontext = UIGraphicsGetCurrentContext(); 227 CGContextDrawImage(subcontext, rect, subImageRef); 228 229 UIImage * image = [UIImage imageWithCGImage:subImageRef scale:scale orientation:UIImageOrientationUp]; 230 UIGraphicsEndImageContext(); 231 232 CGImageRelease(subImageRef); //这里不必释放 233 UIGraphicsEndImageContext(); 234 235 return image; 236 } 237 @end
这份代码iphone开发秘籍这本书中给的,实现了开头介绍的3种缩放方法。下面会详细的分析这份代码。
+ (CGSize) fitSize: (CGSize)thisSize inSize: (CGSize) aSize; 计算出合适的尺寸
+ (UIImage *) image: (UIImage *) image fitInSize: (CGSize) size;成比例缩放,不裁剪,需重新测量尺寸
+ (UIImage *) image: (UIImage *) image centerInSize: (CGSize) size;不需要再重新测量,可能裁剪
+ (UIImage *) image: (UIImage *) image centerInSize: (CGSize) size;可能需要裁剪和重新测量,每个像素都会被使用
开始逐个介绍每一种缩放方法究竟是怎么实现的:
1、fitSize: (CGSize)thisSize inSize: (CGSize) aSize;第一个参数是原图尺寸,第二个是新View的尺寸
根据原图的尺寸,成比例的计算出新图的尺寸。
新图尺寸初始化:CGSize newSize = thisSize;先令新图的尺寸等于原图的尺寸
计算缩放比例:原W/原H = 新W/新H
1、fitInSize的实现
image: (UIImage *) image fitInSize: (CGSize) size; 第一个参数是原图,第二个参数是要构建的新图的尺寸
成比例的缩放自然要先
待写。。。