利用 UIView 的 mask 設計特別形狀的圖片

彼得潘看到【在沒有你以後】的封面和 MV 後, 覺得人物頭像融合風景的風格超 Cool 的 ! 一般這樣的效果可以利用一些美術軟體做到,不過彼得潘美術不好,所以就試試用 Swift 程式製作特別形狀的圖片吧。

以去背的 image view 當 mask

1 找兩張準備融合的圖片。

彼得潘找了一張陰影的頭像和紐西蘭知名的瓦納卡孤樹,待會我們將融合兩張圖片,讓頭像顯示湖上美麗的孤樹。

找圖時建議找兩張大小差不多的圖片,因為我們的做法是切割孤樹的風景照,讓風景照只顯示頭像形狀的區塊,概念類似以下的示意圖。

我們希望實現右邊的畫面

在 google 搜尋剪影 png 或 Silhouette png。

2 利用 Preview App 去背,只留下黑色影子的區塊。

將下圖頭像以外的地方去背,到時候跟孤樹的風景照融合時,風景照只會顯示影子照片裡有顏色的區塊,其它去背的部分則會被遮蔽。以下圖為例,風景照會變成頭像的形狀。

3 將圖片加到 playground。

4 撰寫 Swift 程式。

import UIKit

let treeImage = UIImage(named: "tree.jpg")
let treeImageView = UIImageView(image: treeImage)
let headImage = UIImage(named: "head.png")
let headImageView = UIImageView(image: headImage)
treeImageView.mask = headImageView

說明

(1) 加入 UIKit 函式庫。

import UIKit

UI 相關的東西定義在 UIKit framework 裡。加入 UIKit,我們才能撰寫 UI 相關的程式,使用 UIImage 和 UIImageView 。

(2) 產生顯示瓦納卡孤樹的 image view。

let treeImage = UIImage(named: "tree.jpg")
let treeImageView = UIImageView(image: treeImage)

畫面上負責顯示圖片的是 image view,它的型別是 UIImageView。它顯示的圖片內容則由型別 UIImage 的東西控制,因此我們利用 UIImage(named: "tree.jpg") 生成圖片,存在 treeImage,然後在生成 UIImageView 時傳入 treeImage。

ps: 點選 playground 右邊圓形的 Quick Look & 長方形的 Show Result,將可進一步看到程式執行的結果,比方剛剛顯示的瓦納卡孤樹圖片。

(3) 產生顯示頭像的 image view。

let headImage = UIImage(named: "head.png")
let headImageView = UIImageView(image: headImage)

(4) 設定孤樹的遮罩(mask)為頭像圖片。

treeImageView.mask = headImageView

mask 中文是遮罩的意思,它是型別 UIView 的屬性。treeImageView 的型別是 UIImageView,而 UIImageView 又繼承 UIView,因此 treeImageView 也擁有 mask 屬性。

經由設定 view 元件的 mask,我們將讓 view 只顯示 mask 裡非透明的區塊,其它部分被遮起來。

treeImageView.mask = headImageView 將孤樹照的 mask 設為頭像照,長方形的 treeImageView 變成只顯示 headImageView 裡非透明的區塊,也就是頭像黑色的區塊。

也許有人有疑問,headImageView 的型別是 UIImageView ,而 mask 的型別是 UIView,為什麼可以寫 treeImageView.mask = headImageView 呢 ? 別忘了,UIImageView 繼承 UIView,因此 headImageView 也算是 UIView,所以可以存入 mask。

mask 的相關說明。

以顯示 SF Symbols 的 image view 當 mask

let treeImageView = UIImageView(image: UIImage(named: "tree.jpg"))
treeImageView.frame = CGRect(x: 0, y: 0, width: 300, height: 300)
let wifiImageView = UIImageView(image: UIImage(systemName: "wifi"))
wifiImageView.frame = treeImageView.frame
treeImageView.mask = wifiImageView

以顯示 emoji 的 label 當 mask

製作星形圖片

import UIKit

let treeImage = UIImage(named: "tree.jpg")
let treeImageView = UIImageView(image: treeImage)
let label = UILabel(frame: treeImageView.frame)
label.text = "⭑"
label.font = UIFont.systemFont(ofSize: 800)
label.textAlignment = NSTextAlignment.center
treeImageView.mask = label

漸層的 mask

import UIKit

let treeImage = UIImage(named: "tree.jpg")
let treeImageView = UIImageView(image: treeImage)
let gradientLayer = CAGradientLayer()
gradientLayer.frame = treeImageView.bounds
gradientLayer.colors = [
CGColor(red: 1, green: 1, blue: 1, alpha: 0),
CGColor(red: 1, green: 1, blue: 1, alpha: 1)
]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 0, y: 1)
treeImageView.layer.mask = gradientLayer
treeImageView

漸層由上而下愈來愈清楚,因此當我們將漸層設為圖片的 mask 時,圖片將由上而下愈來愈清楚。

影片的 mask

只要學會利用 UIView 的 mask,我們即可創作任何形狀的圖片。那麼影片呢 ? 有沒有可能在情人節跟女朋友一起看部心形的電影呢 ? 當然也可以呀,相關介紹可參考以下連結。

作業

1 利用 UIView 的 mask 設計特別形狀的圖片,並且改變圖片的顏色,比方下圖的風景染上了一抹紅。

2 利用 UIView 的 mask 設計特別形狀的圖片,並且融合兩張照片。

練習中

解答(請不要偷看,先練習再看呀)

1 利用 UIView 的 mask 設計特別形狀的圖片,並且改變圖片的顏色,比方下圖的風景染上了一抹紅。

import UIKit

let treeImage = UIImage(named: "tree.jpg")
let treeImageView = UIImageView(image: treeImage)
let headImage = UIImage(named: "head")
let headImageView1 = UIImageView(image: headImage)
treeImageView.mask = headImageView1
let redView = UIView(frame: treeImageView.frame)
redView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.5)
let headImageView2 = UIImageView(image: headImage)
redView.mask = headImageView2
treeImageView.addSubview(redView)

2 利用 UIView 的 mask 設計特別形狀的圖片,並且融合兩張照片。

import UIKit

let treeImage = UIImage(named: "tree.jpg")
let treeImageView = UIImageView(image: treeImage)
let headImage = UIImage(named: "head")
let headImageView1 = UIImageView(image: headImage)
treeImageView.mask = headImageView1
treeImageView.alpha = 0.5
let snowImage = UIImage(named: "snow.jpg")
let snowImageView = UIImageView(image: snowImage)
snowImageView.alpha = 0.5
let headImageView2 = UIImageView(image: headImage)
snowImageView.mask = headImageView2
let backgroundView = UIView(frame: treeImageView.frame)
backgroundView.addSubview(treeImageView)
backgroundView.addSubview(snowImageView)

作品集

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com