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用,比如表情~實現沒有看懂,待研究。。。  
        
 
       