iOS圖片拉伸技巧

来源:http://www.cnblogs.com/androidshouce/archive/2016/07/18/5680016.html
-Advertisement-
Play Games

縱觀移動市場,一款移動app,要想長期在移動市場立足,最起碼要包含以下幾個要素:實用的功能、極強的用戶體驗、華麗簡潔的外觀。華麗外觀的背後,少不了美工的辛苦設計,但如果開發人員不懂得怎麼合理展示這些設計好的圖片,將會糟蹋了這些設計,功虧一簣。 比如下麵張圖片,本來是設計來做按鈕背景的: button ...


縱觀移動市場,一款移動app,要想長期在移動市場立足,最起碼要包含以下幾個要素:實用的功能、極強的用戶體驗、華麗簡潔的外觀。華麗外觀的背後,少不了美工的辛苦設計,但如果開發人員不懂得怎麼合理展示這些設計好的圖片,將會糟蹋了這些設計,功虧一簣。

比如下麵張圖片,本來是設計來做按鈕背景的:

 button.png,尺寸為:24x60

現在我們把它用作為按鈕背景,按鈕尺寸是150x50:

複製代碼
  1. // 得到view的尺寸  
  2. CGSize viewSize = self.view.bounds.size;  
  3.   
  4. // 初始化按鈕  
  5. UIButton *button = [[UIButton alloc] init];  
  6. // 設置尺寸  
  7. button.bounds = CGRectMake(0, 0, 150, 50);  
  8. // 設置位置  
  9. button.center = CGPointMake(viewSize.width * 0.5f, viewSize.height * 0.5f);  
  10.   
  11. // 載入圖片  
  12. UIImage *image = [UIImage imageNamed:@"button"];  
  13. // 設置背景圖片  
  14. [button setBackgroundImage:image forState:UIControlStateNormal];  
  15.   
  16. // 添加按鈕  
  17. [self.view addSubview:button];  
複製代碼

運行效果圖:

可以看到,效果非常地差。原因很簡單,因為原圖大小為24x60,現在整張圖片被全方位拉伸為150x50,比較嚴重的是圖片的4個角。

有些人可能馬上想到一個解決方案,你叫美工把圖片做大一點不就好了麽,怎麼拉伸都沒事。沒錯,這是一種解決方案,不過不建議採取。原因很簡單:1.圖片大,導致安裝包也大,載入到記憶體中也大;2.有更好的解決方案。

細看一下圖片,其實圖片會變得難看,完全是因為4個角被拉伸了,中間的拉伸並沒有明顯地醜化外觀。因此要想小圖片被拉伸後不會變得難看,在圖片拉伸的時候,我們只需拉伸圖片的中間一塊矩形區域即可,不要拉伸邊緣部分。

比如只拉伸下圖的矩形區域,上下左右的邊緣都不拉伸:

iOS中提供很好用的API幫我們實現上述功能。到iOS 6.0為止,iOS提供了3種圖片拉伸的解決方案,接下來分別詳細介紹這些方案。

一、iOS 5.0之前

iOS中有個叫端蓋(end cap)的概念,用來指定圖片中的哪一部分不用拉伸。比如下圖中,黑色代表需要被拉伸的矩形區域,上下左右不需要被拉伸的邊緣就稱為端蓋。

使用UIImage的這個方法,可以通過設置端蓋寬度返回一個經過拉伸處理的UIImage對象

 

  1. - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;  

 

這個方法只有2個參數,leftCapWidth代表左端蓋寬度,topCapHeight代表頂端蓋高度。系統會自動計算出右端蓋寬度(rightCapWidth)和底端蓋高度(bottomCapHeight),演算法如下:

 

[java] view plaincopy
  1. // width為圖片寬度  
  2. rightCapWidth = width - leftCapWidth - 1;  
  3.   
  4. // height為圖片高度  
  5. bottomCapHeight = height - topCapHeight - 1  

 

經過計算,你會發現中間的可拉伸區域只有1x1

 

 
  1. // stretchWidth為中間可拉伸區域的寬度  
  2. stretchWidth = width - leftCapWidth - rightCapWidth = 1;  
  3.       
  4. // stretchHeight為中間可拉伸區域的高度  
  5. stretchHeight = height - topCapHeight - bottomCapHeight = 1;  

 

因此,使用這個方法只會拉伸圖片中間1x1的區域,並不會影響到邊緣和角落。

下麵演示下方法的使用:

複製代碼  
  1. // 左端蓋寬度  
  2. NSInteger leftCapWidth = image.size.width * 0.5f;  
  3. // 頂端蓋高度  
  4. NSInteger topCapHeight = image.size.height * 0.5f;  
  5. // 重新賦值  
  6. image = [image stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight];  
複製代碼

調用這個方法後,原來的image並不會發生改變,會產生一個新的經過拉伸的UIImage,所以第6行中需要將返回值賦值回給image變數

運行效果:

可以發現,圖片非常美觀地顯示出來了

註意:

1.這個方法在iOS 5.0出來後就過期了

2.這個方法只能拉伸1x1的區域

 

二、iOS 5.0

在iOS 5.0中,UIImage又有一個新方法可以處理圖片的拉伸問題

 

 
  1. - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets  

 

這個方法只接收一個UIEdgeInsets類型的參數,可以通過設置UIEdgeInsets的left、right、top、bottom來分別指定左端蓋寬度、右端蓋寬度、頂端蓋高度、底端蓋高度

複製代碼
  1. CGFloat top = 25; // 頂端蓋高度  
  2. CGFloat bottom = 25 ; // 底端蓋高度  
  3. CGFloat left = 10; // 左端蓋寬度  
  4. CGFloat right = 10; // 右端蓋寬度  
  5. UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);  
  6. // 伸縮後重新賦值  
  7. image = [image resizableImageWithCapInsets:insets];  
複製代碼

運行效果:

 

三、iOS 6.0

在iOS6.0中,UIImage又提供了一個方法處理圖片拉伸

 

  1. - (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode  

 

對比iOS5.0中的方法,只多了一個UIImageResizingMode參數,用來指定拉伸的模式:

  • UIImageResizingModeStretch:拉伸模式,通過拉伸UIEdgeInsets指定的矩形區域來填充圖片
  • UIImageResizingModeTile:平鋪模式,通過重覆顯示UIEdgeInsets指定的矩形區域來填充圖片

 

 
  1. CGFloat top = 25; // 頂端蓋高度  
  2. CGFloat bottom = 25 ; // 底端蓋高度  
  3. CGFloat left = 10; // 左端蓋寬度  
  4. CGFloat right = 10; // 右端蓋寬度  
  5. UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right);  
  6. // 指定為拉伸模式,伸縮後重新賦值  
  7. image = [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];  

 

運行效果:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 電話撥號器(重點) 1.產品經理: 需求分析文檔,設計原型圖 2.UI工程師: 設計UI界面 3.架構師: 寫架構,介面文檔 4.碼農: 服務端,客戶端 1.寫佈局界面 2.寫業務邏輯 1.通過佈局文件中對控制項配置的id,在activity中可以獲取控制項的對象,Edittext Button fin ...
  • 1.線性佈局 LinearLayout orientation:方向;vertical,垂直;horizontal,水平 gravity:對齊方式,子控制項相對於當前控制項的對齊方式 layout_gravity:當前控制項相對於父控制項的對齊方式 margin:當前控制項相對於四周的間距。 padding: ...
  • 在啟動篇中我們詳細分析了TaintDroid對DVM方法參數和方法變數的變數級污點跟蹤機制,現在我們將繼續分析TaintDroid對類的靜態域、實例域以及數組的污點跟蹤。 ...
  • DBFarmer是PowerFramework資料庫管理工具的集合。 可以進行對象的存儲,添加了setter和getter的參數會被收錄到資料庫中,每個參數作為一個項,int類型的id或_id會被作為primary key。 資料庫名為DBFarmer.db,在項目目錄下。每個對象的表名為類的全名替 ...
  • 鎖屏作為一種黑白屏時代就存在的手機功能,至今仍發揮著巨大作用,特別是觸屏時代的到來,鎖屏的功用被髮揮到了極致。多少人曾經在無聊的時候每隔幾分鐘劃開鎖屏再關上,孜孜不倦,其酸爽程度不亞於捏氣泡膜。 ...
  • 1Add JAR 從Eclipse的現有所有工程中,添加jar包到該工程下 2Add External JARs 從Eclipse外的其他的位置,添加jar包到該工程下 3Add Variable 增加一個變數 4Add Library 增加一個庫 5Add Class Folder 從Eclips ...
  • /etc/hosts 把host 複製到桌面 修改 然後 替換原來的 ...
  • 一,工程圖。 二,代碼。 AppDelegate.m ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...