相冊(cè)(-album)是預(yù)裝的一款集圖片查看、管理功能于一體的圖片管理工具,有著外觀時(shí)尚、性能流暢的特點(diǎn)。目前已支持50余種圖片格式的導(dǎo)入和展示,基本上能滿足絕大多數(shù)用戶的日常圖片的使用場(chǎng)景。部分格式列舉如下:
BMP ICO JPG JPE JPS JPEG JNG KOALA KOA LBM MNG PBM PNM PBMRAW PCD PCX PGM PGMRAW PNG PPM PPMRAW RAS TGA TARGA TIFF TIF WBMP PSD CUT XBM XPM DDS GIF FAX G3 SGI EXR J2C JPC PCT PIC PICT RAW WEBP JXR MNG SVG ICNS MRW DNG RAF CR2 MEF ORF NEF PEF PXM
為提升用戶的使用體驗(yàn),解決不同格式的圖片具備不同編碼方式的問(wèn)題,基于Qt開(kāi)發(fā)的相冊(cè)應(yīng)用采用了和相結(jié)合的方式對(duì)圖片進(jìn)行了統(tǒng)一的解碼、轉(zhuǎn)換和渲染繪制。
接下來(lái),本文將從技術(shù)實(shí)現(xiàn)角度,介紹相冊(cè)應(yīng)用在加載圖片文件后的轉(zhuǎn)換和處理過(guò)程。
1.轉(zhuǎn)換過(guò)程
是一款免費(fèi)、開(kāi)源的圖像處理庫(kù),相冊(cè)應(yīng)用通過(guò)其接口加載圖片后得到的數(shù)據(jù)結(jié)構(gòu)為。但是作為基于Qt開(kāi)發(fā)而來(lái)的相冊(cè)應(yīng)用使用的是來(lái)保存圖像數(shù)據(jù),所以無(wú)法直接通過(guò)Qt進(jìn)行繪制。因此,相冊(cè)應(yīng)用需要將轉(zhuǎn)換成。
其轉(zhuǎn)換過(guò)程如下:
1.通過(guò)pe獲取圖片的真實(shí)格式;
2.獲取的像素寬、高和深度;
3.根據(jù)的像素寬、高和深度值創(chuàng)建一個(gè)相同像素、深度的空對(duì)象;
4.將原始數(shù)據(jù)完整拷貝給對(duì)象,字節(jié)數(shù)與掃描線字節(jié)數(shù)對(duì)應(yīng)。
需要說(shuō)明的是, 圖像深度是指存儲(chǔ)每個(gè)像素所用的位數(shù),用以度量圖像的色彩分辨率和表征單個(gè)像素點(diǎn)的色彩詳細(xì)度。圖像深度值越高,占用的存儲(chǔ)空間就越大,能表達(dá)的顏色數(shù)目就越多。但是一般而言顏色代碼轉(zhuǎn)換表,由于設(shè)備和人眼分辨率的限制,不一定要追求特別深的圖像深度。
2.圖像深度處理
在相冊(cè)應(yīng)用中,對(duì)于圖像深度做了一些特殊的處理,比如:
1.由于Qt暫不支持4位、48位以及48位以上的圖像深度,所以需要采用傳統(tǒng)的位數(shù)轉(zhuǎn)換方法將4位的深度轉(zhuǎn)換成8位輸出:
$$
P=P1*2^n/2^k
$$
其中P為轉(zhuǎn)換后的像素值,P1為轉(zhuǎn)換前的像素值,n為原圖像深度值,k為待轉(zhuǎn)換的深度值。
一般而言,對(duì)于48位及以上高深度值的圖像,圖像源文件較大,加載時(shí)內(nèi)存占用更多,暫不在處理范圍內(nèi)。若想處理高位圖像,可采用位數(shù)轉(zhuǎn)換公式轉(zhuǎn)換到低位,但會(huì)丟失圖像色彩精度,效果受到一定影響。
圖像深度對(duì)應(yīng)Qt格式表如下:
表1 圖像深度與對(duì)應(yīng)轉(zhuǎn)換格式表
深度對(duì)應(yīng)轉(zhuǎn)換格式備注
1
位圖模式
4
Qt不支持4位,轉(zhuǎn)換成8位
8
8位
16
/
需要區(qū)分和
24
RGB32
32
帶alpha通道的RGB24
2.當(dāng)圖像深度為16時(shí),需要區(qū)分和兩種色彩模式(注:RGB是工業(yè)界的一種顏色標(biāo)準(zhǔn)顏色代碼轉(zhuǎn)換表,代表紅、綠、藍(lán)三個(gè)通道的顏色)。區(qū)別在于的每個(gè)像素用16比特位表示占2個(gè)字節(jié),RGB分量都使用5位(最高位不用);而的每個(gè)像素用16比特位表示占2個(gè)字節(jié),RGB分量分別使用5位、6位、5位。它們的對(duì)比如圖1所示。
圖1 與對(duì)比
3.編碼實(shí)現(xiàn)
根據(jù)上述的轉(zhuǎn)換流程,在編碼實(shí)現(xiàn)時(shí)既可按照規(guī)則進(jìn)行內(nèi)存拷貝,也可使用提供的函數(shù)來(lái)做轉(zhuǎn)換實(shí)現(xiàn),通過(guò)傳入已經(jīng)初始化完畢的對(duì)象的引用、原數(shù)據(jù)和圖像深度,即可得到轉(zhuǎn)換后的最終數(shù)據(jù)。
部分代碼如下:
int width ?= static_cast<int>(FreeImage_GetWidth(dib)); //像素寬度 ? ?
int height = static_cast<int>(FreeImage_GetHeight(dib));//像素高度 ? ?
int depth = static_cast<int>(FreeImage_GetBPP(dib)); //深度值 ? ?
switch (depth) { ? ? ?
? ...
? case 8: { ? ? ? ?
? ? QImage result(width, height, QImage::Format_Indexed8);//創(chuàng)建QImage對(duì)象 ? ?
? ? FreeImage_ConvertToRawBits(result.scanLine(0), dib, result.bytesPerLine(), 8, 0, 0, 0, true); ?//執(zhí)行轉(zhuǎn)換 ?
? } ? ? ?
? ?case 16: {
? ? ? ?if ( // 5-5-5
? ? ? ? ? (FreeImage_GetRedMask(dib) ? == FI16_555_RED_MASK) &&
? ? ? ? ? (FreeImage_GetGreenMask(dib) == FI16_555_GREEN_MASK) &&
? ? ? ? ? (FreeImage_GetBlueMask(dib) ?== FI16_555_BLUE_MASK)) {
? ? ? ? ? ?QImage result(width, height, QImage::Format_RGB555);
? ? ? ? ? ?FreeImage_ConvertToRawBits(
? ? ? ? ? ? ? ?result.scanLine(0), dib, result.bytesPerLine(), 16,
? ? ? ? ? ? ? ?FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK,
? ? ? ? ? ? ? ?true); ?//執(zhí)行轉(zhuǎn)換
? ? ? } else { // 5-6-5
? ? ? ? ? ?QImage result(width, height, QImage::Format_RGB16);
? ? ? ? ? ?FreeImage_ConvertToRawBits(
? ? ? ? ? ? ? ?result.scanLine(0), dib, result.bytesPerLine(), 16,
? ? ? ? ? ? ? ?FI16_565_RED_MASK, FI16_565_GREEN_MASK, FI16_565_BLUE_MASK,
? ? ? ? ? ? ? ?true); //執(zhí)行轉(zhuǎn)換
? ? ? }
? }
? ...
}
如果想轉(zhuǎn),獲取的圖像寬高和深度后調(diào)用將轉(zhuǎn)換成。
以上是針對(duì)轉(zhuǎn)換成的方法介紹。更多圖像編解碼信息、數(shù)字圖像處理方法可查閱《數(shù)字圖像處理》一書(shū)或參考各編碼標(biāo)準(zhǔn)。往期精選| in the past你的虎年專題壁紙來(lái)了!深度操作系統(tǒng)20.4發(fā)布!
開(kāi)源社區(qū)中心正式成立!
你好,!分享那些可能被你忽略的軟件陪我走過(guò)的路星火行動(dòng)啟動(dòng)!