zoukankan      html  css  js  c++  java
  • 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; 第一个参数是原图,第二个参数是要构建的新图的尺寸

    成比例的缩放自然要先

    待写。。。

  • 相关阅读:
    【gtest/gmock】警告与报错集合
    【gtest/gmock】gmock:Mock的常用方法
    【C++容器】vector 和 list 的区别
    【C++百科】C++标准库到底是什么?
    【C++】设置、改变、获取系统环境变量:setenv & putenv & getenv
    【C++调试】error: 编译报错合集
    【C++调试】 warning: 编译警告合集
    Linux常用命令
    tcpdump及wireshark组合使用
    Vim快捷键
  • 原文地址:https://www.cnblogs.com/wyqfighting/p/3183736.html
Copyright © 2011-2022 走看看