预备知识:
1,这里大量使用了CoreGraphics的方法,第一个非常常用的的方法就是
UIKIT_EXTERN void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) NS_AVAILABLE_IOS(4_0);
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的坐标系是不同的,所以需要特殊处理下;
这里他用了修改坐标系的方法来解决,所以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用,比如表情~实现没有看懂,待研究。。。
- 【 js 基础 】【 源码学习 】源码设计 (持续更新)
学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:undersc ...
- 【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)
学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析 第二部分:unders ...
- ActiveMQ学习系列(三)----下载github源码并编译
前记:坚持使用官网的资源去学习是挺痛苦的一个过程,昨天瞎溜达了一天,也没看到有系统性的学习文章,倒是发现了github上的ActiveMq项目. 地址:https://github.com/apach ...
- 在IDEA中搭建Java源码学习环境并上传到GitHub上
打开IDEA新建一个项目 创建一个最简单的Java项目即可 在项目命名填写该项目的名称,我这里写的项目名为Java_Source_Study 点击Finished,然后在项目的src目录下新建源码文件 ...
- 05.ElementUI源码学习:项目发布配置(github pages&npm package)
0x00.前言 书接上文.项目第一个组件已经封装好,说明文档也已编写好.下面需要将说明文档发布到外网上,以此来展示和推广项目,使用 Github Pages功能实现.同时将组件发布之 npm 上,方便 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)
前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...
- MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)
前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)
前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...
- 我的angularjs源码学习之旅2——依赖注入
依赖注入起源于实现控制反转的典型框架Spring框架,用来削减计算机程序的耦合问题.简单来说,在定义方法的时候,方法所依赖的对象就被隐性的注入到该方法中,在方法中可以直接使用,而不需要在执行该函数的时 ...
随机推荐
- 机器指令翻译成 JavaScript —— No.2 跳转处理
上一篇,我们发现大多数 6502 指令都可以直接 1:1 翻译成 JS 代码,但除了「跳转指令」. 跳转指令,分无条件跳转.条件跳转.从另一个角度,也可分: 静态跳转:目标地址已知 动态跳转:目标地址 ...
- 纯JS打造比QQ空间更强大的图片浏览器-支持拖拽、缩放、过滤、缩略图等
在线演示地址(打开网页后,点击商家图册): http://www.sport7.cn/cc/jiangnan/football5.html 先看一看效果图: 该图片浏览器实现的功能如下: 1. 鼠标滚 ...
- Linux 中的数值计算和符号计算
不知道经常需要做科学计算的朋友们有没有这样的好奇:在 Linux 系统下使用什么工具呢?说到科学计算,首先想到的肯定是 Matlab,如果再说到符号计算,那就非 Mathematica 不可了.可惜, ...
- 2000条你应知的WPF小姿势 基础篇<8-14>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师,对C#和WPF有着极深的热情.最为出色的是他维护了两个博客:2,000Things You Should Know ...
- 怎样编写高质量的java代码
代码质量概述 怎样辨别一个项目代码写得好还是坏?优秀的代码和腐化的代码区别在哪里?怎么让自己写的代码既漂亮又有生命力?接下来将对代码质量的问题进行一些粗略的介绍.也请有过代码质量相关经验的朋友 ...
- 如何隐藏DIV对象
DIV对象在网页里面,相当于一个容器,在其内部,可以显示文字.图片.视频控件等等. 以下的教程,和大家一起来学习,如何隐藏DIV对象. 这必须使用CSS来控制,才能达到隐藏的目的,那么,就得使用CSS ...
- tornado session
[转]tornado入门 - session cookie 和session 的区别: 1.cookie数据存放在客户的浏览器上,session数据放在服务器上. 2.cookie不是很安全,别人可以 ...
- vue源码解析阅读列表
https://zhuanlan.zhihu.com/p/24435564 开发vue(或类似的MVVM框架)的过程中,需要面对的主要问题有哪些? 剖析vue实现原理,自己动手实现mvvm 官网介绍
- 前端学HTTP之基本认证
前面的话 人们用Web进行私人事务处理,访问私有的数据.通过Web可以很方便地访问这些信息,但仅仅是方便访问还是不够的.我们要保证只有特定的人能看到我们的敏感信息并且能够执行我们的特权事务 服务器需要 ...
- Node.js:fs文件系统模块
fs文件系统模块,这是一个非常重要的模块,对文件的操作都基于它.该模块的所有方法都有同步和异步两种方式,下面便介绍一下该模块的使用. 1.检测当前进程对文件的权限 使用fs.access(path[, ...