Swift RGB888轉(zhuǎn)RGB565

位圖(Bitmap),又稱柵格圖(英語:Raster graphics)或點(diǎn)陣圖,是使用像素陣列(Pixel-array/Dot-matrix點(diǎn)陣)來表示的圖像督禽。

根據(jù)位深度,可將位圖分為1讲婚、4、8待德、16君丁、24及32位圖像等。每個像素使用的信息位數(shù)越多将宪,可用的顏色就越多绘闷,顏色表現(xiàn)就越逼真,相應(yīng)的數(shù)據(jù)量越大较坛。例如印蔗,位深度為 1 的像素位圖只有兩個可能的值(黑色和白色),所以又稱為二值位圖丑勤。位深度為 8 的圖像有 2^8(即 256)個可能的值华嘹。位深度為 8 的灰度模式圖像有 256 個可能的灰色值。

RGB圖像由三個顏色通道組成法竞。8 位/通道的 RGB 圖像中的每個通道有 256 個可能的值耙厚,這意味著該圖像有 1600 萬個以上可能的顏色值。有時將帶有 8 位/通道 (bpc) 的 RGB 圖像稱作 24 位圖像(8 位 x 3 通道 = 24 位數(shù)據(jù)/像素)岔霸。通常將使用24位RGB組合數(shù)據(jù)位表示的的位圖稱為真彩色位圖薛躬。

在iOS中,Bitmap的數(shù)據(jù)由CGContext封裝呆细,看下CGContext的初始化方法如下:

init?(data: UnsafeMutableRawPointer?, width: Int, height: Int, bitsPerComponent:Int, bytesPerRow: Int, space: CGColorSpace, bitmapInfo: UInt32)

data: UnsafeMutableRawPointer,用于存放位圖的點(diǎn)陣數(shù)據(jù)

width: Int 位圖的寬

height: Int 位圖的高

如width=10,height=10,則代表每一行有10個像素型宝,每一列有20個像素

bitsPerComponent:Int 顏色組件或者alpha組件占的bite數(shù),以32位圖為列:bitsPerComponent = 8

bytesPerRow: Int 位圖每行占的字節(jié)數(shù)(byte)以32位圖為例:一個像素有4byte(rgba)

那么一行字節(jié)數(shù):?bytesPerRow = 4*width

space: CGColorSpac 顏色空間?CGColorSpaceCreateDeviceRGB

bitmapInfo: UInt32?一個常量,描述這個位圖上下文所對應(yīng)的位圖的基本信息趴酣,例如:CGImageAlphaInfo.premultipliedLast

接下來我們以兩種方式把圖片從rgb888轉(zhuǎn)成rgb56

第一種以UInt32來接收位圖信息梨树,即一個數(shù)據(jù)包含了RGBA所有數(shù)據(jù)


func rbg565Data() -> Data? {

????????guard let cgImage = self.cgImage

????????????else { return Data() }

????????let width = Int(size.width)

????????let height = Int(size.height)

????????// bytes array

????????let srcRowBytes = 4 * width

????????var bytes = Array<UInt32>.init(repeating: 0, count: srcRowBytes * height)

????????// create context for image

????????guard let context = CGContext(data: &bytes, width: width, height: height, bitsPerComponent: 8, bytesPerRow: srcRowBytes, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue )

????????????else { return nil }

? ? ? ? // fill buffer

????????context.interpolationQuality = .high

????????context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

????????var newBytes = [UInt8]()

????????for col in 0..<height {

????????????for row in 0..<width {

//????????????????let pixeIndex = (col*width+row)*4

????????????????let color = bytes[(col*width+row)]

????????????????let r = UInt8(( color >> 0 ) & 0xff )

????????????????let g = UInt8(( color >> 8 ) & 0xff )

????????????????let b = UInt8(( color >> 16) & 0xff )

????????????????let data = (r & 0xf8) | ((g >> 5) & 0x7)

????????????????newBytes.append(data)

????????????????let data2 = ((g<<3) & 0xE0) | ((b >> 3) & 0x1F)

????????????????newBytes.append(data2)

????????????}

????????}


????????return Data(bytes: newBytes, count: newBytes.count)


????}

第二種已UInt8來存儲位圖信息,即一個數(shù)據(jù)只包含RGBA中一個通道信息价卤,比如R


func rbg565Data() -> Data? {

????????guard let cgImage = self.cgImage

????????????else { return Data() }

????????let width = Int(size.width)

????????let height = Int(size.height)

????????// bytes array

????????let srcRowBytes = 4 * width

????????var bytes = Array<UInt8>.init(repeating: 0, count: srcRowBytes * height)

????????// create context for image

????????guard let context = CGContext(data: &bytes, width: width, height: height, bitsPerComponent: 8, bytesPerRow: srcRowBytes, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue )

????????????else { return nil }


????????// fill buffer

????????context.interpolationQuality = .high

????????context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

????????var newBytes = [UInt8]()

????????for i in 0..<(bytes.count/4) {

????????????let pixeIndex = i*4

????????????let r = UInt8(bytes[pixeIndex])

????????????let g = UInt8(bytes[pixeIndex+1])

????????????let b = UInt8(bytes[pixeIndex+2])

????????????let data:UInt8 = (r & 0xf8) | ((g >> 5) & 0x7)

????????????newBytes.append(data)

????????????let data2:UInt8 = ((g<<3) & 0xE0) | ((b >> 3) & 0x1F)

????????????newBytes.append(data2)

//????????????logD("---r=\(r),g=\(g),b=\(b),data=\(data),data1=\(data2)")

????????}

????????return Data(bytes: newBytes, count: newBytes.count)


????}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末劝萤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子慎璧,更是在濱河造成了極大的恐慌床嫌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胸私,死亡現(xiàn)場離奇詭異厌处,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)岁疼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門阔涉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人捷绒,你說我怎么就攤上這事瑰排。” “怎么了暖侨?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵椭住,是天一觀的道長。 經(jīng)常有香客問我字逗,道長京郑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任葫掉,我火速辦了婚禮些举,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俭厚。我一直安慰自己户魏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布套腹。 她就那樣靜靜地躺著绪抛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪电禀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天笤休,我揣著相機(jī)與錄音尖飞,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛政基,可吹牛的內(nèi)容都是我干的贞铣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼沮明,長吁一口氣:“原來是場噩夢啊……” “哼辕坝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荐健,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤酱畅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后江场,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纺酸,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年址否,在試婚紗的時候發(fā)現(xiàn)自己被綠了餐蔬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡佑附,死狀恐怖樊诺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情音同,我是刑警寧澤词爬,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站瘟斜,受9級特大地震影響缸夹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜螺句,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一虽惭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蛇尚,春花似錦芽唇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谱邪,卻和暖如春炮捧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惦银。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工咆课, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留末誓,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓书蚪,卻偏偏與公主長得像喇澡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子殊校,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360