對於了解視覺方面的事情平時自然也很有興趣,
所以用 Swift 寫寫圖片相關的東西了解運作也是很正常的。
回到主題,之前是因為看到有人用 Objective-C 寫了一個 Image Dump,
而最近因為寫一個簡報,就順手改寫了個 Swift 的版本,
也把一些筆記整理進來。
先來看一下程式碼,如下:
func imageDump(img:UIImage){ let imageRef = img.CGImage let width = CGImageGetWidth(imageRef) let height = CGImageGetHeight(imageRef) let bytesPerRow = CGImageGetBytesPerRow(imageRef) let bitsPerPixel = CGImageGetBitsPerPixel(imageRef) let colorSpace = CGImageGetColorSpace(imageRef) let bitPerComponent = CGImageGetBitsPerComponent(imageRef); let bytesPerPixel = bitsPerPixel / bitPerComponent; let provider:CGDataProviderRef = CGImageGetDataProvider(imageRef) let data:NSData = CGDataProviderCopyData(provider) let bytes = data.bytes // Needs to be changed to ConstUnsafePointer<()> in xCode beta3 let bytePointer = UnsafePointer(bytes) println("\n") println("Pixel Data:\n") var printString:String = "" for var row:Int = 0; row < Int(height); row++ { for var col:Int = 0; col < Int(width); col++ { printString += "(" for var x = 0; x < Int(bytesPerPixel); x++ { var channel:UInt8 = bytePointer[row * Int(bytesPerRow) + col * Int(bytesPerPixel) + x] printString += NSString(format:"%.2X, ", channel) } printString += ")" if col < Int(width) - 1 { printString += "," } } printString += "\n" } println(printString) }
關於 CGImage 參數
這邊使用的是一張 4 x 3 像素的 png 圖片,
一開始先把 UIImage 轉為 CGImage,
藉由 CGImage 取得一些需要的數據,
println("bytesPerRow",bytesPerRow) //16 println("bitsPerPixel",bitsPerPixel) //32 println("bitPerComponent",bitPerComponent) //8 println("bytesPerPixel",bytesPerPixel) //4bitPerComponent 為 8, 是因為圖片為 ARGB8888。
*關於ARGB8888參考連結
bytesPerPixel 為 4 bytes 是由 bitPerComponent 而來,
R、G、B、A 每個 Channel 都使用 8 bits,
所以每個像素的 R、G、B、A 加起來是 32 bits = 4 bytes。 (1 bit = 8 bytes)
因此 bitsPerPixel 從 bytesPerPixel 換算來就是 32 bits。
bytesPerRow 為 16 是跟圖片的寬度有關,
前面說一個像素是 4 bytes,乘上圖片寬度 4 像素, 就為 16 啦!
*別處對於CGImageRef的參數解釋
println(data) 的話,可以直接看到 4 x 3 的圖片 RGBA 數據
39b64eff fcee09ff 0005e8ff ed1b2eff 00bbf7ff e90189ff fc9512ff fcf006ff ee352bff c9e3daff 3ab84aff 02abecff
關於 row 跟 col 的迴圈
for迴圈那是利用 row(height) 跟 col(width) 來取得每個像素位置,如下圖

關於每個像素 channel 的值
最內層的迴圈for var x = 0; x < Int(bytesPerPixel); x++
x會為0~3,也就是像素的寬度。
在 bytePointer[row * Int(bytesPerRow) + col * Int(bytesPerPixel) + x] 得到的數值可以這樣看
另外,不知道為什麼下面這些程式碼開專案寫可以,但寫在Playground就不行。
let imageRef = img.CGImage let provider:CGDataProviderRef = CGImageGetDataProvider(imageRef) let data:NSData = CGDataProviderCopyData(provider)
其他相關資料:
ROMAIN GUY講位圖質量
關於轉換位圖陣列ARGB8888到RGB565
NBA Draft
ReplyDeleteNBA Draft Live
NBA Draft 2018
NBA Draft 2018 Live
2018 NBA Draft
NBA Draft
NBA Draft Live
NBA Draft 2018
NBA Draft 2018 Live
Watch NBA Draft
Clemson Football
ReplyDeleteClemson Football 2018
Clemson Football Schedule
Clemson Football 2018 Schedule
Clemson Football Live
Clemson Football Live Streaming
Clemson Football Live Stream
Clemson Tigers Football
https://clemsonfootball.de/
I recommend iDealshare VideoGo as the most professional audio converter and video converter.https://www.idealshare.net/3ga-to-mp3-converter.html
ReplyDelete