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 thescaleparameter. -  
    
opaque -  
    
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
 
 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];
 
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用,比如表情~实现没有看懂,待研究。。。  
					