UIImage+YYWebImage是YYWebImage(https://github.com/ibireme/YYWebImage)中的一个分类,这个分类封装了一些image常用的变化方法,非常值得学习下源码~(我看的版本是1.0.5)
 
预备知识:
1,这里大量使用了CoreGraphics的方法,第一个非常常用的的方法就是
UIKIT_EXTERN void    UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) NS_AVAILABLE_IOS(4_0);
 
 
Parameters
size

The size (measured in points) of the new bitmap context. This represents the size of the image returned by the UIGraphicsGetImageFromCurrentImageContext() function. To get the size of the bitmap in pixels, you must multiply the width and height values by the value in thescale parameter.

opaque

A Boolean flag indicating whether the bitmap is opaque. If you know the bitmap is fully opaque, specify true to ignore the alpha channel and optimize the bitmap’s storage. Specifying false means that the bitmap must include an alpha channel to handle any partially transparent pixels.

scale

The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.

 
考虑到UIColor是有透明度的,所以这个方法传入的参数opaque一般传NO;考虑到屏幕的的Scale,所以传入的scale参数一般传0,或者self.scale;
文档有写“This function may be called from any thread of your app.” 所以在任何线程做都没有问题~~
 
 
具体方法:
1, + (UIImage *)yy_imageWithColor:(UIColor *)color size:(CGSize)size;生成一个指定大小的纯色图片;
方法实现比较简单,就是创建一个图片上下文,拿到这个上下文,设置其为指定颜色,填充,取到图片,关闭这个图片上下文,就可以了;
如最开始所说,opaque是NO,scale是0;
如果是用来做背景用的图片,可以直接将size设置为(1,1),然后用系统默认的拉伸效果来把图片放大( UIViewContentModeScaleToFill),这样效率比较高;
YYImage也提供了 + (nullable UIImage *)yy_imageWithColor:(UIColor *)color;这个方法来实现这个功能。
     
2, - (void)yy_drawInRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMode clipsToBounds:(BOOL)clips;
这个方法我感觉应该算是个内部方法,个人感觉没有必要放出来,可能有场景会用到我没遇到过吧;
 
3, - (nullable UIImage *)yy_imageByResizeToSize:(CGSize)size contentMode:(UIViewContentMode)contentMode;按指定的模式生成一个指定大小的图片;size就是生成的图片的大小,多出来的地方是透明的;
这个方法是调用- (void)yy_drawInRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMode clipsToBounds:(BOOL)clips;来实现的。里面用到的 static CGRect _YYCGRectFitWithContentMode(CGRect rect, CGSize size, UIViewContentMode mode)这个方法得值得学习下。这个方法是用来得到按模式放大或者缩小后图片完整的rect,比如:
一张100*200的图片,用 UIViewContentModeScaleAspectFit的模式,放到一个400*400的imageView中,那得到的rect就是(100,0,200,400);
一张100*200的图片,用 UIViewContentModeScaleAspectFill的模式,放到一个400*400的imageView中,那得到的rect就是(0,200,400,800);
。。。。。。
不同的模式会得到不同的rect,生成的图片也会不一样;
具体rect的计算是根据图片的宽高比和目标rect的宽高比来确定的,而不是具体的宽或者高,这个需要特别注意,这完全是为了达到缩放模式的效果而做的数学计算。这里真的很佩服作者!!!
- (UIImage *)yy_imageByResizeToSize:(CGSize)size;没有调用这个方法,而是另外写了一遍,效果跟用这个方法contentModel传 UIViewContentModeScaleToFill是一样的,不知道有啥用意~
 
4, - (nullable UIImage *)yy_imageByCropToRect:(CGRect)rect;裁剪图片中的某个区域
注意裁剪范围只跟image的size有关,跟imageView的大小无关;
如果rect比image的size大,则没有效果,如果rect比image的size小,会剪裁出指定的区域;
 
5, - (nullable UIImage *)yy_imageByInsetEdge:(UIEdgeInsets)insets withColor:(nullable UIColor *)color;根据insets来剪裁图片;
这个方法也很牛X~,注意insets是可以取负数的,如果取负数,就相当与给原来的图片加上指定颜色的边框;
如果为正数,就是根据insets来剪裁图片,这时候color参数无效
 
6, - (UIImage *)yy_imageByRoundCornerRadius:(CGFloat)radius
                                 corners:(UIRectCorner)corners
                             borderWidth:(CGFloat)borderWidth
                             borderColor:(UIColor *)borderColor
                          borderLineJoin:(CGLineJoin)borderLineJoin;
设置圆角的方法
里面用了 CGContextDrawImage(context, rect, self.CGImage);的方法;而CGContext的坐标系与UIKit的坐标系是不同的,所以需要特殊处理下;
具体有什么不同可以参考 http://blog.csdn.net/trandy/article/details/6617272 
这里他用了修改坐标系的方法来解决,所以corners也是颠倒的,需要特殊处理下;
注意这个方法只会设置圆角,如果原来的图片不是正方形的,那怎么设置页不会得到正圆的图片,需要预先把图片裁成正方形的才行;
 
7, - (nullable UIImage *)yy_imageByRotate:(CGFloat)radians fitSize:(BOOL)fitSize;生成旋转指定角度后的图片
fitSize传yes,图片会自动压缩使图片显示完整,传no图片会被截断;
其中 CGRectApplyAffineTransform返回的是“包含旋转后的rect的最小矩形的CGRect”,origin的值可能为负值;
这个方法使用 CGBitmapContextCreate这个方法来绘制的,跟前面的直接用 UIGraphicsGetCurrentContext不太一样,反正我是不太懂。。。
我能看懂的就这么几句:
    CGContextTranslateCTM(context, +(newRect.size.width * 0.5), +(newRect.size.height * 0.5));
    CGContextRotateCTM(context, radians);
   
    CGContextDrawImage(context, CGRectMake(-(width * 0.5), -(height * 0.5), width, height), self.CGImage);
    CGImageRef imgRef = CGBitmapContextCreateImage(context);
    UIImage *img = [UIImageimageWithCGImage:imgRef scale:self.scaleorientation:self.imageOrientation];
    CGImageRelease(imgRef);
这里比较巧妙,貌似CGContext的锚点是在(0,0)的,而image的锚点是在中心点的,所以先移动context到中心点,再从(-(width * 0.5), -(height * 0.5))开始绘图,然后得到CGImageRef,用[UIImageimageWithCGImage:imgRef scale:self.scaleorientation:self.imageOrientation]这个方法来修正坐标系的问题,也是非常值得学习~
 
 
8,- (nullable UIImage *)yy_imageByBlurRadius:(CGFloat)blurRadius
                                 tintColor:(nullable UIColor *)tintColor
                                  tintMode:(CGBlendMode)tintBlendMode
                                saturation:(CGFloat)saturation
                                 maskImage:(nullable UIImage *)maskImage;
图片模糊效果
好用,但实现超出了目前的我的理解范围,待研究。。。
 
9, + (nullableUIImage *)yy_imageWithSmallGIFData:(NSData *)data scale:(CGFloat)scale;
文档说是小型gif用,比如表情~实现没有看懂,待研究。。。 

github源码学习之UIImage+YYWebImage的更多相关文章

  1. 【 js 基础 】【 源码学习 】源码设计 (持续更新)

    学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:undersc ...

  2. 【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)

    学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析 第二部分:unders ...

  3. ActiveMQ学习系列(三)----下载github源码并编译

    前记:坚持使用官网的资源去学习是挺痛苦的一个过程,昨天瞎溜达了一天,也没看到有系统性的学习文章,倒是发现了github上的ActiveMq项目. 地址:https://github.com/apach ...

  4. 在IDEA中搭建Java源码学习环境并上传到GitHub上

    打开IDEA新建一个项目 创建一个最简单的Java项目即可 在项目命名填写该项目的名称,我这里写的项目名为Java_Source_Study 点击Finished,然后在项目的src目录下新建源码文件 ...

  5. 05.ElementUI源码学习:项目发布配置(github pages&npm package)

    0x00.前言 书接上文.项目第一个组件已经封装好,说明文档也已编写好.下面需要将说明文档发布到外网上,以此来展示和推广项目,使用 Github Pages功能实现.同时将组件发布之 npm 上,方便 ...

  6. MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

    前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...

  7. MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)

    前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...

  8. MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)

    前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...

  9. 我的angularjs源码学习之旅2——依赖注入

    依赖注入起源于实现控制反转的典型框架Spring框架,用来削减计算机程序的耦合问题.简单来说,在定义方法的时候,方法所依赖的对象就被隐性的注入到该方法中,在方法中可以直接使用,而不需要在执行该函数的时 ...

随机推荐

  1. 2DToolkit官方文档中文版打地鼠教程(二):设置摄像机

    这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...

  2. 我想立刻辞职,然后闭关学习编程语言,我给自己3个月时间学习C语言!这样行的通吗

    文章背景,回答提问:我想立刻辞职,然后闭关学习编程语言,我给自己3个月时间学习C语言!这样行的通吗? 我的建议是这样:1. 不要辞职.首先说,你对整个开发没有一个简单的了解,或一个系统的入门学习.换句 ...

  3. Asp.Net跨平台:Ubuntu14.0+Mono+Jexus+Asp.Net

    Asp.Net跨平台的文章园子里有很多,这里给自己搭建的情况做一下总结,方便以后查看. 参考网站:   http://www.linuxdot.net/(Linux DotNET大本营 )  http ...

  4. AutoMapper(二)

    返回总目录 首先,先创建一个控制台项目,引用AutoMapper程序集,创建三个类User,UserDto,UserMappingProfile,下面的知识点的演示都以此项目为基础,代码分别如下: n ...

  5. MongoDB与PostgresQL无责任初步测试

    PostgresQL一秒能插入多少条记录,MongoDB呢?读取的情况又如何?我写了一些简单的程序,得出了一些简单的数据,贴在这里分享,继续往下阅读前请注意下本文标题中的“无责任”,这表示此测试结果不 ...

  6. 自己写jquery插件之模版插件高级篇(一)

    需求场景 最近项目改版中,发现很多地方有这样一个操作(见下图gif动画演示),很多地方都有用到.这里不讨论它的用户体验怎么样. 仅仅是从复用的角度,如果每个页面都去写text和select元素,两个b ...

  7. 访问IIS网站需要输入用户名密码(非匿名登录)问题汇总

    无语了,最近不少Windows服务器都出现这个访问网站需要输入的问题,而且每次解决方法还不一样...唉,先汇总下解决方法吧,有时间再仔细研究下这些问题是如何导致的. 当IIS已启用"允许匿名 ...

  8. .NET里简易实现IoC

    .NET里简易实现IoC 前言 在前面的篇幅中对依赖倒置原则和IoC框架的使用只是做了个简单的介绍,并没有很详细的去演示,可能有的朋友还是区分不了依赖倒置.依赖注入.控制反转这几个名词,或许知道的也只 ...

  9. nodejs模块中exports和module.exports的区别

    通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require('模块名')去获取:核心 ...

  10. SQL Server 多实例下的复制

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 搭建步骤(Procedure) 注意事项(Attention) 二.背景(Contexts) ...