iOS——寫一個快速定位問題的指令碼

小魚周凌宇發表於2017-12-14

image

你是否見過?

  1. 你是否見過測試人員或者自己在 CI 上 install 了一個版本,發現了 BUG 後,突然忘了自己下的是 CI 上的哪一個 commit 的包?
  2. 你是否見過下面這個東西:

blog_iOS——寫一個快速定位問題的指令碼-01

blog_iOS——寫一個快速定位問題的指令碼-02

寫一個這樣一個指令碼

可以寫這樣一個指令碼,它能做到:

  1. 在 Build 的過程中在 App Icon 的表面覆蓋上 Build 號、分支名、commit version 的 hash 值
  2. 不影響原本的 App Icon 圖示原始檔
  3. 區分 ReleaseDebug,只在 Debug 環境下 Build 專案時執行指令碼

Do it

ImageMagick

做後端的同學們,大多知道 ImageMagick

使用 ImageMagick 可以建立、編輯、合成或轉換圖片。它可以讀和寫各種格式的影象(超過 200 種格式)包括 PNG、JPEG、JPEG - 2000、GIF、TIFF、DPX、EXR、WebP、Postscript、PDF、SVG。ImageMagick 可以調整、翻轉、映象、旋轉、扭曲、剪下和轉換影象、影象色彩調整,適用於各種特殊效果,或繪製文字、線、多邊形、橢圓和貝塞爾曲線。

通過 shell command 就可以輕易使用以上功能。


讓我們來看一些基本的。這是我們準備好的 120*120 的原圖:

blog_iOS——寫一個快速定位問題的指令碼-03

cd 到圖片所在的目錄,執行以下命令,給圖片新增高斯模糊效果:

convert original.png -blur 10x8 blurred.png
複製程式碼

完成圖:

blog_iOS——寫一個快速定位問題的指令碼-04


繼續,執行以下命令從 座標 (0,60) 剪下成 120*60 的圖片,

convert blurred.png -crop 120x60+0+60 cropped-blurred.png
複製程式碼

完成圖:

blog_iOS——寫一個快速定位問題的指令碼-05


繼續,給圖片新增文字水印『zhoulingyu』,引數包括:背景不填充顏色、白色字型、字型大小 12、居中顯示文字、文字為『zhoulingyu』:

convert -background none -fill white -pointsize 12 -gravity center caption:"zhoulingyu" cropped-blurred.png +swap -composite label.png
複製程式碼

完成圖:

blog_iOS——寫一個快速定位問題的指令碼-06


繼續,將上面得到的剪下好的帶水印的 label.png 和 原圖 original.png 合成在一起:

composite label.png original.png finished-image.png
複製程式碼

完成圖:

blog_iOS——寫一個快速定位問題的指令碼-07

OK,我們得到了想要的效果圖。

引數參考

給出一些 ImageMagic 的常用用法:

  1. 檢視圖片資訊
identify original.png 
original.png PNG 120x120 120x120+0+0 8-bit sRGB 46c 2.58KB 0.010u 0:00.000
複製程式碼
  1. 格式轉換
convert original.png original.jpg 
複製程式碼
  1. 編輯圖片大小
convert original.png -resize 200x200 resize-image.png 
複製程式碼
  1. 裁剪
# 從座標 (0,0) 裁剪 100*100 的影象
convert original.png -crop 100x100+0+0 crop.png  
複製程式碼
  1. 旋轉
convert original.png -rotate 45 rotate.png 
複製程式碼
  1. 合併影象
# 給圖片新增水印
convert original.png -compose over watermark.png -composite new-image.png  
複製程式碼
  1. 高斯模糊
convert -blur 80x5 original.jpg blur.png
複製程式碼

-blur radiusxsigma,兩個分別是高斯模糊需要的兩個引數,具體可以檢視 blur 引數使用

ImageMagick 可以實現 N 多效果,像油畫、噪聲、散射、旋渦,都不在話下。

除了基本的效果,還有一些比較常用的引數:

引數名 使用規範 說明 用例
-background -background color 設定背景色 -background white
-pointsize -pointsize value 設定字型等大小 -pointsize 12
-gravity -gravity type 為其他命令附加 gravity,比如設定文字新增位置居中。 -gravity Center
-geometry -geometry geometry 設定即將處理影象的座標位置 -geometry +0+60 -geometry Center

當然這些都可以在 官方文件 找到。

shell 指令碼

1. 基本設定

知道 ImageMagic 如何使用,剩下來寫指令碼就思路清晰多了。

在工程 Target -> Build Phases 中新建一個 Run Script,我們可以給它起名 generate auxiliary icon,這樣稍後容易在 Report Navigator 觀察。

blog_iOS——寫一個快速定位問題的指令碼-08

現在我們可以開始編寫我們的指令碼 auxiliary_icon.sh

2. 理思路

寫虛擬碼通常能夠幫助我自己更清晰的寫程式碼:

// 1. 判斷執行 Build 的機器是否安裝了 ImageMagic
//    |- 如果沒有安裝:提示安裝,退出指令碼
//    |- 如果安裝:繼續執行
// 2. 獲取 commit 號 hash 值、分支名、build 號,並將其拼接成一個字串
// 3. 判斷編譯環境
//    |- 如果是 Release 環境:提示當前是 Release 環境,退出指令碼
//    |- 如果是非 Release 環境:繼續執行
// 4. 獲取 Plist 中 CFBundleIconFiles 的數量
// 5. 根據數量迴圈,執行呼叫『生成記號圖方法』


// 『生成記號圖方法』 
// function generateIcon() {
// 1. 模糊圖片
// 2. 擷取圖片下半部分
// 3. 新增 commit+brach+build 組成的字串在擷取圖片上
// 4. 合成擷取圖片和原圖
// 5. 清除多餘圖片
// }
複製程式碼

虛擬碼寫好了,開始編寫正式程式碼:

  1. 判斷執行 Build 的機器是否安裝了 ImageMagic

which 一下就知道

convertPath=`which convert`
# 判斷 convertPath 檔案是否存在
if [ ! -f ${convertPath}]; then
echo "==============
WARNING: 你需要先安裝 ImageMagick!!!!:
brew install imagemagick
=============="
exit 0;
fi
複製程式碼
  1. 獲取 commit 號 hash 值、分支名、build 號,並將其拼接成一個字串

PlistBuddy 可以用於讀取 Plist 檔案,通過描述路徑就可以找到你想知道的 Key 對應的 Value。 ${INFOPLIST_FILE} 是 xcodebuild 提供的變數(具體可以參考 Build settings reference)提供了編譯後 info.plist 的路徑。

commit=`git rev-parse --short HEAD`
branch=`git rev-parse --abbrev-ref HEAD`
buildNumber=`/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_FILE}"`
caption="${buildNumber} \n${branch}\n${commit}"
複製程式碼
  1. 判斷編譯環境
# Release 不執行
echo "Configuration: $CONFIGURATION"
if [ ${CONFIGURATION} = "Release" ]; then
exit 0;
fi
複製程式碼
  1. 獲取 Plist 中 CFBundleIconFiles 的數量

在編譯後的 info.plist 中,可以找到如下結構:

blog_iOS——寫一個快速定位問題的指令碼-09

這裡記錄了所有的 Icon files。檢視 plist 的原格式,可以看到原始的 key 是什麼。通過 PlistBuddy 和 路徑 CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles 可以輸出 value。

| wc -l 可以統計輸出行數。

icon_count=`/usr/libexec/PlistBuddy -c "Print CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles" "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}" | wc -l`
複製程式碼

要注意的是, /usr/libexec/PlistBuddy -c "Print CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles" "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}" 輸出結果是這樣的:

blog_iOS——寫一個快速定位問題的指令碼-10

輸出一共是 五行,所以獲得的結果是 5。

那麼真實的 CFBundleIconFiles count 其實是:

real_icon_index=$((${icon_count} - 2))
複製程式碼

剛開始,我也沒有注意。可想而知心情如何 =_=。

blog_iOS——寫一個快速定位問題的指令碼-11

  1. 根據數量迴圈,執行呼叫『生成記號圖方法』
for ((i=0; i<$real_icon_index; i++)); do
# 找到 icon 名
icon=`/usr/libexec/PlistBuddy -c "Print CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles:$i" "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"`

# 呼叫 generateIcon 方法,傳入 icon 名
generateIcon "${icon}@2x.png"

done
複製程式碼
  1. generateIcon 方法
function generateIcon() {
    originalImg=$1

    cd "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"

    # 驗證存在性
    if [[ ! -f ${originalImg} || -z ${originalImg} ]]; then
    return;
    fi

    # 進入編譯後的工程目錄
    cd "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/"

    # 新增高斯模糊
    convert ${originalImg} -blur 10x8 blur-original.png

    # 擷取下部分
    width=`identify -format %w ${originalImg}`
    height=`identify -format %h ${originalImg}`
    height_0=`expr ${height} / 2`
    height_1=$((${height} - ${height_0}))
    convert blur-original.png -crop ${width}x${height_0}+0+${height_1} crop-blur-original.png

    # 加字
    point_size=$(((8 * $height) / 58))

    convert -background none -fill white -pointsize ${point_size} -gravity center caption:"${caption}" crop-blur-original.png +swap -composite label.png

    # 合成
    composite -geometry +0+${height_0} label.png ${originalImg} ${originalImg}

    # 清除檔案
    rm blur-original.png
    rm crop-blur-original.png
    rm label.png
}
複製程式碼

程式碼清單

最終的程式碼清單放在了 Github 上:

ZLYWatermarkIcon

參考

Command-line Tools:Convert 使用ImageMagick新增圖片水印-Linux krzysztofzablocki/IconOverlaying Overlaying application version on top of your icon 我的ImageMagick使用心得 高斯模糊的演算法 Build settings reference Shell指令碼程式設計30分鐘入門


有什麼問題都可以在博文後面留言,或者微博上私信我,或者郵件我 coderfish@163.com

博主是 iOS 妹子一枚。

希望大家一起進步。

我的微博:小魚周凌宇

相關文章