iOS 简单的图片缩放

前言:还是这个图片浏览的小demo,在里面实现了对单张图片的放大缩小。现在把我已知的图片缩放的各种方法记录下来,方便以后查阅,毕竟图片缩放还是经常用到的。

正文:构建图像缩略图,通常有3种形式:保持图像比例不变调整大小;裁剪部分图像来匹配可用空间;通过匹配可用空间的长度和宽度来填充图像。

一、最简单的方法
UIGraphicsBeginImageContext(size); //size 为CGSize类型,即你所需要的图片尺寸
[sourceImage drawInRect:newImageRect]; //sourceImage为原图,newImageRect指定了图片绘制区域
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

OK,newImage 就是你要的图。缺点:回丢失很多图片信息
 
二、利用UISrcollView的方法 

  _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;
}

 

三、自己写缩放方法
我们一般会写一个ImageHelper类,在这个类中实现图片的尺寸调整等所有功能。先附上代码:
 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
ImageHelper.h
  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
ImageHelper.m

这份代码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; 第一个参数是原图,第二个参数是要构建的新图的尺寸

成比例的缩放自然要先

待写。。。

posted @ 2013-07-11 12:57  little_star  阅读(1536)  评论(0编辑  收藏  举报