關(guān)于圖片的一些認(rèn)識(shí)

在項(xiàng)目開(kāi)發(fā)中使用 SDWebImage 來(lái)做圖片緩存加載然低,但是遇到一個(gè)問(wèn)題就是服務(wù)器的某一張圖片始終無(wú)法加載出來(lái),通過(guò)URL拿到原圖之后可以正常查看逼争。于是追根溯源定位到了 SDWebImage 中的 decodedImageWithImage 方法中,也給自己科普了一下圖像處理的相關(guān)知識(shí)。

下面先了解圖像的一些基礎(chǔ)知識(shí)冕象,然后分析遇到的問(wèn)題。

基礎(chǔ)知識(shí)

圖像可以分為矢量圖和位圖酣衷,我們通常使用的圖像為位圖格式交惯,這種格式又分為幾種顏色模型,如 RGB,CMYK 等穿仪,分別適用于不同的場(chǎng)景席爽。

我們常用的 RGB 則是通過(guò)顏色發(fā)光原理來(lái)設(shè)計(jì)的。其分為紅(R)啊片、綠(G)只锻、藍(lán)(B)三個(gè)顏色通道,每個(gè)通道的數(shù)值表示該通道的明暗程度紫谷,根據(jù)單位像素所占空間不同齐饮,其又可以分為RGB1,RGB2,RGB4,RGB8,RGB16,RGB24,RGB32等多種格式捐寥,其中RGB1、RGB2,RGB4,RGB8為調(diào)色板類(lèi)型的RGB格式祖驱,即需要通過(guò)顏色索引表來(lái)描述顏色信息握恳,RGB16為高彩色(Hi Color),RGB24為真彩色(TRUE COLOR)捺僻,RGB32則帶Aphal通道(RGBA)乡洼。

對(duì)于 RGB16,其實(shí)也是通過(guò)調(diào)色板實(shí)現(xiàn)的匕坯,可以分為 RGB444,RGB565,RGB555三種方式束昵,后面的三個(gè)數(shù)字分別表示三個(gè)通道的數(shù)據(jù)位數(shù),RGB565 表示紅(R)、藍(lán)(B)各占5位,綠(G)占三位佣盒,即單像素的表示方式為:RRRRRGGGGGGBBBBB勇劣,之所以綠色使用6位是因?yàn)槿搜蹖?duì)綠色的辨識(shí)程度比較高。而RGB555表示為 XRRRRRGGGGGBBBBB ,其中 X 表示該位不使用,由于每個(gè)顏色使用5位表示,所以每個(gè)通道最多包含32種不同亮度值榛丢,相關(guān)的索引表也就需要把亮度從明到暗均分成32份,可以通過(guò)使用屏蔽字和移位操作來(lái)得到RGB各分量的值:

#define RGB555_MASK_RED 0x7C00
#define RGB555_MASK_GREEN 0x03E0
#define RGB555_MASK_BLUE 0x001F
R = (wPixel & RGB555_MASK_RED) >> 10; // 取值范圍0-31
G = (wPixel & RGB555_MASK_GREEN) >> 5; // 取值范圍0-31
B = wPixel & RGB555_MASK_BLUE; // 取值范圍0-31

然后通過(guò) RGB 的取值在索引表中得到真實(shí)的顏色挺庞。
索引顏色是一種位圖圖像的編碼方法晰赞。當(dāng)真彩色圖片轉(zhuǎn)換為索引顏色的圖片時(shí),如果原圖顏色不在索引顏色中选侨,計(jì)算機(jī)會(huì)從索引顏色中選出一個(gè)相近的顏色來(lái)模擬該顏色(抖動(dòng)到相近的顏色)掖鱼,這也是早期瀏覽器存在 web 安全色的原因。要了解 web 安全色 的歷史援制,可以戳這里

對(duì)于 RGB24 使用24位表示一個(gè)像素戏挡,RGB分量都用8位表示,取值范圍為0-255晨仑。RGB32 則多了一個(gè)8位的 alpha 通道來(lái)表示透明度褐墅,可以使用RGBQUAD數(shù)據(jù)結(jié)構(gòu)來(lái)操作一個(gè)像素:

typedef struct tagRGBQUAD {
BYTE rgbBlue; // 藍(lán)色分量
BYTE rgbGreen; // 綠色分量
BYTE rgbRed; // 紅色分量
BYTE rgbReserved; // 保留字節(jié)(用作Alpha通道或忽略)
} RGBQUAD。

顯然洪己,對(duì)于 RGB24 和 RGB32 妥凳,每個(gè)通道都使用8位表示,即每個(gè)通道有256中不同的色彩深度答捕。那么逝钥,如果每個(gè)通道使用16位甚至32位來(lái)表示,那就用有更多的顏色深度了拱镐。包含 32 位/通道的圖像也稱(chēng)作高動(dòng)態(tài)范圍(HDR)圖像艘款。

查看 CGBitmapContextCreate 的函數(shù)定義:

CG_EXTERN CGContextRef __nullable CGBitmapContextCreate(void * __nullable data,
    size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow,
    CGColorSpaceRef cg_nullable space, uint32_t bitmapInfo)
    CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

Create a bitmap context. The context draws into a bitmap which is width pixels wide and height pixels high. The number of components for each pixel is specified by space, which may also specify a destination color profile. The number of bits for each component of a pixel is specified by bitsPerComponent. The number of bytes per pixel is equal to (bitsPerComponent * number of components + 7)/8. Each row of the bitmap consists of bytesPerRow bytes, which must be at least width * bytes per pixel bytes; in addition, bytesPerRow must be an integer multiple of the number of bytes per pixel. data, if non-NULL, points to a block of memory at least bytesPerRow * height bytes. If data is NULL, the data for context is allocated automatically and freed when the context is deallocated. bitmapInfo specifies whether the bitmap should contain an alpha channel and how it’s to be generated, along with whether the components are floating-point or integer.

翻譯如下:

創(chuàng)建一個(gè)位圖 context持际,位圖的像素通過(guò) width、hight 指定哗咆。每一個(gè)像素的顏色個(gè)數(shù)(number of components 通道數(shù))通過(guò) space 指定蜘欲,也可以通過(guò)一個(gè)顏色描述文件來(lái)指定。每像素中每個(gè)顏色占用的位空間(bit)通過(guò) bitsPerComponent 參數(shù)指定岳枷。每個(gè)像素的字節(jié)數(shù)(bytes per pixel)通過(guò)公式 (bitsPerComponent * number of components + 7)/8 計(jì)算(這個(gè)加7應(yīng)該是為了位對(duì)齊)芒填。位圖的每一行包含 bytesPerRow 字節(jié),其最少需要 width * bytes per pixel 字節(jié)空繁;此外,bytesPerRow 必須是 bytes per pixel 的整數(shù)倍朱庆。data 如果不為空盛泡,其指向一個(gè)至少 bytesPerRow * height 字節(jié)的內(nèi)存空間。若 data 為空娱颊,context 的 data 會(huì)隨著該 context 自動(dòng)創(chuàng)建和銷(xiāo)毀傲诵。bitmapInfo 指出該位圖是否包含 alpha 通道和它是如何產(chǎn)生的(RGB/RGBA/RGBX…),還有每個(gè)通道應(yīng)該用整數(shù)標(biāo)識(shí)還是浮點(diǎn)數(shù)箱硕。

關(guān)于 decodedImageWithImage 方法

在我們使用 UIImage 的時(shí)候拴竹,創(chuàng)建的圖片通常不會(huì)直接加載到內(nèi)存,而是在渲染的時(shí)候再進(jìn)行解壓并加載到內(nèi)存剧罩。這就會(huì)導(dǎo)致 UIImage 在渲染的時(shí)候效率上不是那么高效栓拜。為了提高效率通過(guò) decodedImageWithImage 方法把圖片提前解壓加載到內(nèi)存,這樣這張新圖片就不再需要重復(fù)解壓了惠昔,提高了渲染效率幕与。這是一種空間換時(shí)間的做法。

在UI渲染的時(shí)候镇防,實(shí)際上是把多個(gè)圖層按像素疊加計(jì)算的過(guò)程啦鸣,需要對(duì)每一個(gè)像素進(jìn)行 RGBA 的疊加計(jì)算。當(dāng)某個(gè) layer 的是不透明的来氧,也就是 opaque 為 YES 時(shí)诫给,GPU 可以直接忽略掉其下方的圖層,這就減少了很多工作量啦扬。這也是調(diào)用 CGBitmapContextCreate 時(shí) bitmapInfo 參數(shù)設(shè)置為忽略掉 alpha 通道的原因中狂。

轉(zhuǎn)發(fā)自: http://honglu.me/2016/09/02/一張圖片引發(fā)的深思/?utm_source=tuicool&utm_medium=referral

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市考传,隨后出現(xiàn)的幾起案子吃型,更是在濱河造成了極大的恐慌,老刑警劉巖僚楞,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勤晚,死亡現(xiàn)場(chǎng)離奇詭異枉层,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)赐写,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)鸟蜡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人挺邀,你說(shuō)我怎么就攤上這事揉忘。” “怎么了端铛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵泣矛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我禾蚕,道長(zhǎng)您朽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任换淆,我火速辦了婚禮哗总,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倍试。我一直安慰自己讯屈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布县习。 她就那樣靜靜地躺著涮母,像睡著了一般。 火紅的嫁衣襯著肌膚如雪准颓。 梳的紋絲不亂的頭發(fā)上哈蝇,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音攘已,去河邊找鬼炮赦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛样勃,可吹牛的內(nèi)容都是我干的吠勘。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼峡眶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼剧防!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起辫樱,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤峭拘,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸡挠,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辉饱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拣展。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彭沼。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖备埃,靈堂內(nèi)的尸體忽然破棺而出姓惑,到底是詐尸還是另有隱情,我是刑警寧澤按脚,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布于毙,位于F島的核電站,受9級(jí)特大地震影響辅搬,放射性物質(zhì)發(fā)生泄漏望众。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一伞辛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夯缺,春花似錦蚤氏、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至捏境,卻和暖如春于游,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背垫言。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工贰剥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筷频。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓蚌成,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親凛捏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子担忧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • BMP文件格式,又稱(chēng)為Bitmap(位圖)或是DIB(Device-Independent Device坯癣,設(shè)備無(wú)關(guān)...
    我是嘻哈大哥閱讀 4,684評(píng)論 0 1
  • 轉(zhuǎn)載請(qǐng)帶上出處, 謝謝. 一個(gè) Graphics Context 代表一個(gè)繪制目標(biāo), 它包含繪制系統(tǒng)用于完成繪制指...
    Falme丶閱讀 1,787評(píng)論 0 2
  • 步入研究僧階段已經(jīng)有兩月有余了瓶盛,無(wú)論是思想上還是情感上都想找個(gè)地方宣泄一下。 作為一個(gè)信奉「生命在于折騰」的程序員...
    蓋蓋背著超人飛閱讀 217評(píng)論 0 1
  • 今日通過(guò)閱讀《最重要的兩小時(shí)》這本書(shū),讓我印象深刻的是惩猫,其一芝硬,在打算專(zhuān)注做事的時(shí)候腦袋會(huì)走神,做白日夢(mèng)等現(xiàn)象都是正...
    林子Amy閱讀 127評(píng)論 0 0
  • 文/居里社 四季牌陣 1帆锋,權(quán)杖王后:尊貴如你吵取,在這一季擁有著強(qiáng)大的力量,高貴锯厢,堅(jiān)定皮官,權(quán)杖王后代表堅(jiān)強(qiáng)的有力量的人,...
    居里葉閱讀 2,353評(píng)論 0 2