iOS应用开发中对UIImage进行截取和缩放的方法详解

截取UIImage指定大小区域
最近遇到这样的需求:从服务器获取到一张照片,只需要显示他的左半部分,或者中间部分等等。也就是截取UIImage指定大小区域。

UIImage扩展:

我的解决方案是对UIImage进行扩展。通过CGImageRef和CGImage完成截取,调用的方法是:CGImageCreateWithImageInRect。扩展类叫UIImage+Crop,具体代码如下:

UIImage+Crop.h

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, XYCropImageStyle){
  XYCropImageStyleRight        =0,   // 右半部分
  XYCropImageStyleCenter       =1,   // 中间部分
  XYCropImageStyleLeft        =2,   // 左半部分
  XYCropImageStyleRightOneOfThird   =3,   // 右侧三分之一部分
  XYCropImageStyleCenterOneOfThird  =4,   // 中间三分之一部分
  XYCropImageStyleLeftOneOfThird   =5,   // 左侧三分之一部分
  XYCropImageStyleRightQuarter    =6,   // 右侧四分之一部分
  XYCropImageStyleCenterRightQuarter =7,   // 中间右侧四分之一部分
  XYCropImageStyleCenterLeftQuarter  =8,   // 中间左侧四分之一部分
  XYCropImageStyleLeftQuarter     =9,   // 左侧四分之一部分
};

@interface UIImage (Crop)
- (UIImage *)imageByCroppingWithStyle:(XYCropImageStyle)style;

@end
UIImage+Crop.m

#import "UIImage+Crop.h"

@implementation UIImage (Crop)

- (UIImage *)imageByCroppingWithStyle:(XYCropImageStyle)style
{
  CGRect rect;
  switch (style) {
    case XYCropImageStyleLeft:
      rect = CGRectMake(0, 0, self.size.width/2, self.size.height);
      break;
    case XYCropImageStyleCenter:
      rect = CGRectMake(self.size.width/4, 0, self.size.width/2, self.size.height);
      break;
    case XYCropImageStyleRight:
      rect = CGRectMake(self.size.width/2, 0, self.size.width/2, self.size.height);
      break;
    case XYCropImageStyleLeftOneOfThird:
      rect = CGRectMake(0, 0, self.size.width/3, self.size.height);
      break;
    case XYCropImageStyleCenterOneOfThird:
      rect = CGRectMake(self.size.width/3, 0, self.size.width/3, self.size.height);
      break;
    case XYCropImageStyleRightOneOfThird:
      rect = CGRectMake(self.size.width/3*2, 0, self.size.width/3, self.size.height);
      break;
    case XYCropImageStyleLeftQuarter:
      rect = CGRectMake(0, 0, self.size.width/4, self.size.height);
      break;
    case XYCropImageStyleCenterLeftQuarter:
      rect = CGRectMake(self.size.width/4, 0, self.size.width/4, self.size.height);
      break;
    case XYCropImageStyleCenterRightQuarter:
      rect = CGRectMake(self.size.width/4*2, 0, self.size.width/4, self.size.height);
      break;
    case XYCropImageStyleRightQuarter:
      rect = CGRectMake(self.size.width/4*3, 0, self.size.width/4, self.size.height);
      break;
    default:
      break;
  }
  CGImageRef imageRef = self.CGImage;
  CGImageRef imagePartRef = CGImageCreateWithImageInRect(imageRef, rect);
  UIImage *cropImage = [UIImage imageWithCGImage:imagePartRef];
  CGImageRelease(imagePartRef);
  return cropImage;
}

实际运用:

简单测试一下,看看有没有实现我们想要的效果。首先,先加载一个完整的UIImageView。这个应该不难。代码如下:

UIImageView *imgView = [[UIImageView alloc] init];
imgView.frame = CGRectMake((SCREEN.width - 226) / 2, 100, 226, 106);
UIImage *image = [UIImage imageNamed:@"ganggang"];
imgView.image = image;
[self.view addSubview:imgView];

运行一下:

要对UIImage进行裁剪,首先导入头文件:

#import "UIImage+Crop.h"

在上面UIImage *image = [UIImage imageNamed:@"ganggang"];这段代码之后加上下面这句:

image = [image imageByCroppingWithStyle:XYCropImageStyleLeft];

XYCropImageStyleLeft是截取照片的左半部分。效果如下:

截取成功,还可以截取其他区域的,只需要传入不同的XYCropImageStyle即可实现。

UIImage等比缩放
前面讲了截取UIImage指定大小区域,很方便的截取UIImage。今天要和大家分享的是UIImage的缩放。

两种缩放:

  • 缩放到指定大小,也就是指定的size.
  • 等比缩放。

1.缩放到指定大小

- (UIImage*)imageCompressWithSimple:(UIImage*)image scaledToSize:(CGSize)size
{
  UIGraphicsBeginImageContext(size);
  [image drawInRect:CGRectMake(0,0,size.width,size.height)];
  UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return newImage;
}

2.等比缩放

(1)通过缩放系数:

- (UIImage*)imageCompressWithSimple:(UIImage*)image scale:(float)scale
{
  CGSize size = image.size;
  CGFloat width = size.width;
  CGFloat height = size.height;
  CGFloat scaledWidth = width * scale;
  CGFloat scaledHeight = height * scale;
  UIGraphicsBeginImageContext(size); // this will crop
  [image drawInRect:CGRectMake(0,0,scaledWidth,scaledHeight)];
  UIImage* newImage= UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return newImage;
}

scale是缩放系数 。

(2)通过计算得到缩放系数

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
{

  UIImage *sourceImage = [UIImage imageNamed:@"test.jpg"];
  UIImage *newImage = nil;
  CGSize imageSize = sourceImage.size;
  CGFloat width = imageSize.width;
  CGFloat height = imageSize.height;
  CGFloat targetWidth = targetSize.width;
  CGFloat targetHeight = targetSize.height;
  CGFloat scaleFactor = 0.0;
  CGFloat scaledWidth = targetWidth;
  CGFloat scaledHeight = targetHeight;
  CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

  if (CGSizeEqualToSize(imageSize, targetSize) == NO)
  {
    CGFloat widthFactor = targetWidth / width;
    CGFloat heightFactor = targetHeight / height;
    if (widthFactor > heightFactor)
      scaleFactor = widthFactor; // scale to fit height
    else
      scaleFactor = heightFactor; // scale to fit width

    scaledWidth= width * scaleFactor;
    scaledHeight = height * scaleFactor;
    // center the image
    if (widthFactor > heightFactor)
    {
      thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
    }
    else if (widthFactor < heightFactor)
    {
      thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
    }
  }

  UIGraphicsBeginImageContext(targetSize); // this will crop
  CGRect thumbnailRect = CGRectZero;
  thumbnailRect.origin = thumbnailPoint;
  thumbnailRect.size.width= scaledWidth;
  thumbnailRect.size.height = scaledHeight;
  [sourceImage drawInRect:thumbnailRect];
  newImage = UIGraphicsGetImageFromCurrentImageContext();

  if(newImage == nil)
    NSLog(@"could not scale image");
  //pop the context to get back to the default
  UIGraphicsEndImageContext();

  return newImage;

}
(0)

相关推荐

  • iOS应用开发中使用UIScrollView控件来实现图片缩放

    一.知识点简单介绍 1.UIScrollView控件是什么? (1)移动设备的屏幕⼤大⼩小是极其有限的,因此直接展⽰示在⽤用户眼前的内容也相当有限 (2)当展⽰示的内容较多,超出⼀一个屏幕时,⽤用户可通过滚动⼿手势来查看屏幕以外的内容 (3)普通的UIView不具备滚动功能,不能显⽰示过多的内容 (4)UIScrollView是一个能够滚动的视图控件,可以⽤用来展⽰示⼤大量的内容,并且可以通过滚 动查看所有的内容 (5)  举例:手机上的"设置".其他⽰示例程序 2.UIScrollV

  • iOS使用UIScorllView实现两指缩放功能

    两指缩放功能不仅可以用UIPinchGestureRecognizer手势来实现,还能用UIScorllView来实现,UIScrollView可以轻松的实现最大与最小缩放值,以及滚动的效果.代码如下: #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; @property (strong, nonat

  • iOS开发中Quartz2D控制圆形缩放和实现刷帧效果

    Quartz2D简要回顾 一.什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF 截图\裁剪图片 自定义UI控件 二.Quartz2D在iOS开发中的价值 为了便于搭建美观的UI界面,iOS提供了UIKit框架,⾥⾯有各种各样的UI控件 UILabel:显⽰文字 UIImageView:显示图片 UIButton:同时显示图片和⽂

  • iOS实现点击微信头像(放大、缩放、保存)效果

    先来看看实现效果(GIF): 实现思路: 直接自定义 UIView(CYPhotoPreviewer),为了实现双击缩放,可以实现 UIScrollViewDelegate 对应的方法.如果需要模糊背景,可以在自定义的 UIView 中先添加模糊背景,再添加 UIScrollView,继而在 UIScrollView 中添加图片容器,这个容器就是要显示的图片的 superView,代码一目了然: - (void)setup { self.frame = [UIScreenmainScreen].

  • iOS手势识别的详细使用方法(拖动,缩放,旋转,点击,手势依赖,自定义手势)

    手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. 1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了UIGestureRecognizer类.手势识别UIGestureRecognizer类是个抽象类,下面的子类是具体的手势,开发这可以直接使用这些手势识别. UITapGestureRecognizer UI

  • iOS UITableView展开缩放动画实例代码

    Swift - UITableView展开缩放动画 效果 源码:https://github.com/YouXianMing/Swift-Animations // // HeaderViewTapAnimationController.swift // Swift-Animations // // Created by YouXianMing on 16/8/9. // Copyright © 2016年 YouXianMing. All rights reserved. // import

  • iOS应用开发中对UIImage进行截取和缩放的方法详解

    截取UIImage指定大小区域 最近遇到这样的需求:从服务器获取到一张照片,只需要显示他的左半部分,或者中间部分等等.也就是截取UIImage指定大小区域. UIImage扩展: 我的解决方案是对UIImage进行扩展.通过CGImageRef和CGImage完成截取,调用的方法是:CGImageCreateWithImageInRect.扩展类叫UIImage+Crop,具体代码如下: UIImage+Crop.h #import <UIKit/UIKit.h> typedef NS_ENU

  • Android开发中使用WebView控件浏览网页的方法详解

    本文实例讲述了Android开发中使用WebView控件浏览网页的方法.分享给大家供大家参考,具体如下: 项目中遇到数学展示问题,常规的Textview显示处理不了数学公式,利用图片生成对服务器又产生较大压力,经过查询,可以通过webview加载JS实现.IOS同样的方法也可实现,但JS渲染效率远高于安卓.对Webview做下总结. 1.WebView 在使用WebView控件时,首先需要在xml布局文件中定义一个WebView控件,定义的方法如下: <WebView android:id=&quo

  • Python脚本开发中的命令行参数及传参示例详解

    目录 sys模块 argparse模块 Python中的正则表达式 正则表达式简介 Re模块 常用的匹配规则 sys模块 在使用python开发脚本的时候,作为一个运维工具,或者是其他工具需要在接受用户参数运行时,这里就可以用到命令行传参的方式,可以给使用者一个比较友好的交互体验. python可以使用 sys 模块中的 sys.argv 命令来获取命令行参数,其中返回的参数是一个列表 在实际开发中,我们一般都使用命令行来执行 python 脚本 使用终端执行python文件的命令:python

  • JS中call/apply、arguments、undefined/null方法详解

    a.call和apply方法详解 -------------------------------------------------------------------------------- call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call 方法可以用来代替另一个对象调用一个方法.call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指

  • 关于java中可变长参数的定义及使用方法详解

    JAVA中可以为方法定义可变长参数( Varargs)来匹配不确定数量的多个参数,其定义用"..."表示.其实,这类似于为方法传了一个数组,且在使用方法上也和数组相同,如下: public void test(String... str){ for(String s : str){ } } 调用方法就像普通的调用方式相同,只不过可以匹配的参数为0到多个.如下: test(); test("lilei"); test("lilei","h

  • 对python中xlsx,csv以及json文件的相互转化方法详解

    最近需要各种转格式,这里对相关代码作一个记录,方便日后查询. xlsx文件转csv文件 import xlrd import csv def xlsx_to_csv(): workbook = xlrd.open_workbook('1.xlsx') table = workbook.sheet_by_index(0) with codecs.open('1.csv', 'w', encoding='utf-8') as f: write = csv.writer(f) for row_num

  • 对Python中一维向量和一维向量转置相乘的方法详解

    在Python中有时会碰到需要一个一维列向量(n*1)与另一个一维列向量(n*1)的转置(1*n)相乘,得到一个n*n的矩阵的情况.但是在python中, 我们发现,无论是".T"还是"np.transpose"都无法实现一维向量的转置,相比之下,Matlab一句" a' "就能实现了. 那怎么实现呢?我找了个方法.请看: 即,我们把向量reshape一下,如此便实现了一维向量与一维向量转置相乘为矩阵的目的. 若大家有其他方法望告知. 以上这篇对

  • 在Pycharm中对代码进行注释和缩进的方法详解

    一.注释 1. #单行注释 2. """ 多行注释 """ 3. pycharm多行注释快捷键:Ctrl+/ 二.缩进 缩进:Tab 反向缩进:Shift+Tab 以上这篇在Pycharm中对代码进行注释和缩进的方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • 对numpy中二进制格式的数据存储与读取方法详解

    使用save可以实现对numpy数据的磁盘存储,存储的方式是二进制.查看使用说明,说明专门提到了是未经压缩的二进制形式.存储后的数据可以进行加载或者读取,通过使用load方法. In [81]:np.save('demo',data1) 通过以上操作,数据data1被存储到了demo文件中,numpy会自动加上npy的文件后缀名. In [82]: a =np.load('demo.npy') In [83]: a Out[83]: array([0,1, 2, 3, 4, 5, 6, 7, 8

  • c++中的单例类模板的实现方法详解

     1.什么是单例模式 在架构设计时,某些类在整个系统生命周期中最多只能有一个对象存在 ( Single Instance ).如超市收银系统,其外观主要由显示器(1个).扫描枪(1个).收款箱(1个)组成,在系统正常运行期间这三部分都是唯一存在的:也就是说,显示器.扫描枪.收款箱这三部分都应该有各自的类,并且每个类只能唯一地实例化一个对象,基于这种模式的程序设计,称为单例模式. !!!单例模式只能创建一个对象,且该对象的生命周期伴随系统的整个运行期间. 2.怎么实现单例模式 思考:如何定义一个类

随机推荐