github源碼學習之UIImage+YYWebImage

来源:http://www.cnblogs.com/Phelthas/archive/2016/10/20/5982687.html
-Advertisement-
Play Games

UIImage+YYWebImage是YYWebImage(https://github.com/ibireme/YYWebImage)中的一個分類,這個分類封裝了一些image常用的變化方法,非常值得學習下源碼~(我看的版本是1.0.5) 預備知識: 1,這裡大量使用了CoreGraphics的方 ...


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);   蘋果的官方文檔在這兒 https://developer.apple.com/reference/uikit/1623912-uigraphicsbeginimagecontextwitho   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用,比如表情~實現沒有看懂,待研究。。。 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • TextView 顯示文本框控制項, EditText 輸入文本框 ...
  • SharedPreferences 一種輕量級的數據保存方式 以鍵值對的方式存儲 用於存儲小批量的數據 使用方法: SharedPreferences sp= getSharedPreferences("myopt"(文件名),Context.MODE_PRIVATE(數據存儲方式)); 存儲文件名 ...
  • 手機APP在日常生活中越來越與我們息息相關,既然這些APP是用戶每天都必須接觸到的,所以APP更應該從用戶的角度來進行設計。APP開發並沒有什麼固定的法則,也沒有現成的模式可依,只有不斷從用戶的實踐中,從用戶的一言一行當中去考慮用戶的體驗才能設計出用戶體驗良好的APP。 ...
  • Android Weekly中文筆記, Issue #227. 本期內容包括: Google的Mobile Vision API 人臉檢測; Firebase的Remote Config; 與HashMap有關的優化; 提高RecyclerView幀率的優化; 使用AutoValue生成model代... ...
  • 當需要實現一個自定義佈局圖片和標題的按鈕時候,不知道有多少少年直接佈局了UIButton,亦或是自定義一個UIView,然後以空白UIButton、UILabel、UIImageVew作為subViews。 兩者其實都一樣,因為UIButton的內部subViews中,就已經存在一個UILabel和 ...
  • 前言 iOS extension的出現,方便了用戶查看應用的服務,比如用戶可以在Today的widgets中查看應用的簡略信息,然後點擊進入相關的應用界面。暫且不表網路上現有的widget文章,本篇文章主要說明本人具體實現widget的步驟,希望能夠幫助到需要實現widget的同行朋友。 圖1 To ...
  • 1.顯示隱藏系統進程 修改ProcessManagerActivity的Adapter 2.鎖屏清理 ...
  • 1.本進程不能被選中,所以先將checkbox隱藏掉--手機衛士 不能自殺 2.清理選中進程 3.ProcessInfoProvider.java 1 package com.itheima.mobilesafe74.engine; 2 3 import java.io.BufferedReader ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...