Xcode 對於 png 圖片的處理 (Compress PNG Files)


將數據寫入圖片,能夠達到很好的隱藏信息的目的。看到一些地方有相關的方式,我也嘗試了下,然后遇到了問題。Xcode 編譯運行后 Products 里面的可執行文件 讀取不到我的信息。但是我將工程中的 png 圖片手動覆蓋生成的 App 中的圖片后 又能讀取到信息了。

很顯然這倆文件不一樣,但是怎么會不一樣呢? 

通過比對文件md5  驗證了我的想法。 一開始懷疑 Xcode 緩存,通過重新編譯排除了。 或者 文件引用路徑出了問題  一直在搜索這個文件哪里來的。將工程發給其他機器,編譯發現問題依然存在,所以也排除了引用路徑的可能

 

后來同事提醒  Xcode 會對圖片進行優化,恍然大悟。

1、那么 Xcode 會做些什么呢?

Xcode 的 Build Setting 設置里面有一個 Compress PNG Files 的選項, 如果選擇了 YES, 那么 Xcode 在編譯階段將會對所有 png 圖片進行壓縮。

調用這個路徑下的腳本 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/iphoneos-optimize 進行優化 

 它減少PNG IDAT數據流的大小,通過嘗試不同的壓縮級別和PNG篩選方法。它也可以用來去除不必要的輔助塊。

標准的24bit PNG文件存儲方式是按照順序(紅/綠/藍/透明度)這樣來存每一個像素即RGBA,而經過Xcode優化之后的PNG文件像素順序變成了BGRA,這樣的非標准的PNG文件在一般操作系統也就沒辦法讀了。 蘋果這么做是有原因的,在OpenGL的wiki有一篇文章 提到了絕大部分GPU的圖像/紋理顯存每個單元都是24bit的,RGBA和BGRA都有,但BGRA是主流的。 這樣就說得通了:蘋果為了減少圖像運算時花在數據交換(從文件系統到顯示出來)的時間,運用了類似DMA的原理,圖形數據可以在總線里直接走而不用花掉CPU的時間去協助處理。
 
最終變成了一個 優化后的 CgBI 格式的 png。有關 CgBI 的介紹這里有: http://iphonedevwiki.net/index.php/CgBI_file_format 。 它跟 png 的區別是
extra critical chunk (CgBI) 額外的關鍵數據塊 CgBI byteswapped (RGBA -> BGRA) pixel data, presumably for high-speed direct blitting to the framebuffer 字節轉換 加快數據交換 zlib header, footer, and CRC removed from the IDAT chunk 移除 一些輔助性數據塊 premultiplied alpha (color' = color * alpha / 255) Alpha 預乘

它是通過 Xcode 自帶的一個工具 pngcrush 來做的. 在這個位置 

/Applications/Xcode.app/Contents/Developer/usr/bin

這個工具是開源的.  地址在這里:  https://github.com/Kjuly/pngcrush

 

2、Xcode 是根據什么來做這些處理的呢?

由於對於每一個png 圖片,在編譯階段進行處理 不可能根據數據內容來處理 如果這樣,圖片數量多的話 會極大的影響編譯速度。我大膽推測是根據圖片后綴來處理的

進行驗證。果然,將 .png 去掉就沒有處理了!

這里  還找到一種方式能夠避免 png 優化,就是修改 Xcode 對於 png 圖片的類型識別

 改成:

 

 

3、在 OSX10.8之前 系統也無法識別壓縮后的PNG,會導致 png 無法顯示

xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations -q Local.png Local-standard.png

通過這樣可以恢復 標准的 png

 

參考:

apple 官方提供的 恢復優化前 png 方式

Xcode 執行優化的原理

另外:

iOS 開發中 各種壓縮相關的軟件介紹

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM