天天看點

/LGC圖形渲染/常見顔色深度的 bitmap 之間的互相轉換

常見顔色深度的 bitmap 之間的互相轉換 作者: 劉鵬 日期: 2009-08-14 本文介紹了常見色深的格式轉換原理和算法。

簡介

在很多場合中會遇到不同顔色深度的 surface 之間的轉化問題,如筆者在開發 一個虛拟 framebuffer 時就需要将客戶 GUI 系統的顔色深度轉換成虛拟 framebuffer 給定的顔色深度,根據工作中的實際經驗,筆者總結了在幾對典型 的顔色深度之間進行轉換的思路和實作方法,讀者在此基礎可以舉一反三,處理 更多的轉換。

16 位色轉成 24 位色

16位色有兩種格式,一種是565, 另一種是555,本文以 565 格式為例。

對于 16 位色的 surface,一個像素由兩個位元組表示,其中 R 顔色分量占 5 位, G 顔色分量占6 位,B 顔色分量占 5 位。

24 位色的 surface,一個像素由三個位元組表示,R、G、B 分量各占 8 位。

要将 16 位色轉換成 24 位色,需要将565布局的 R、B、G 分量取出來,分别填 充到三個位元組中去,注意要填充時放在高位,末位補 0 ,否則誤差會放大,分 拆情況如下圖所示:

/LGC圖形渲染/常見顔色深度的 bitmap 之間的互相轉換
圖1

實作轉換的代碼如下所示:

for (row = 0;row < src_buffer_height; row++) {

        sp = src_buf + src_buf_pitch * row;

	dp = dst_buf + dst_buf_pitch * row;



        for (col = 0; col < src_buffer_width; col++) {

                word = *((Uint16*)sp);

                sp+=2;



                *dp++ = ((word & 0xF800) >> 11) << 3; /* red */

                *dp++ = ((word & 0x07E0) >> 5) << 2;  /* green */

                *dp++ = (word & 0x001F) << 3;         /* blue */

        }

}

      

4 位色轉為 8 位色

對于 4 位色 surface,每個像素由 4 位表示,每個位元組可表示兩個像素;

對于 8 位色 surface,每個像素由 8 位表示,每個位元組表示一個像素;

要将 4 位色轉換成 8 位色,需要一個位元組的高 4 位和低 4 位分别轉成一個字 節,如下圖所示:

/LGC圖形渲染/常見顔色深度的 bitmap 之間的互相轉換
圖2

完成轉化的示例代碼如下所示:

for (row = 0;row < src_buffer_height; row++) {

        sp = src_buf + src_buf_pitch * row;

	dp = dst_buf + dst_buf_pitch * row;



        for (col = 0; col < src_buffer_width; col++) {

                bit = (col% 2) << 2;

                if (bit == 0)

                c = *sp++;

                *dp++ = (c >> bit) & 0x0f;

        }

}

      

2 位色轉為 8 位色

對于 2 位色 surface,每個像素由 2 位表示,每個位元組可表示四個像素;

對于 8 位色 surface,每個像素由 8 位表示,每個位元組表示一個像素;

要将 2 位色轉換成 8 位色,需要一個位元組按兩位為一個單元分拆,然後将每個 單元填充成一個位元組,如下圖所示:

/LGC圖形渲染/常見顔色深度的 bitmap 之間的互相轉換
圖3

轉換的實作代碼如下所示:

for (row = 0;row < src_buffer_height; row++) {

        sp = src_buf + src_buf_pitch * row;

	dp = dst_buf + dst_buf_pitch * row;



        for (col = 0; col < src_buffer_width; col++) {

                bit = (col% 4) << 1;

                if (bit == 0)

                c = *sp++;

                *dp++ = (c >> bit) & 0x03;

        }

}

      

1 位色轉為 8 位色

對于 1 位色 surface,每個像素由 1 位表示,每個位元組可表示八個像素;

對于 8 位色 surface,每個像素由 8 位表示,每個位元組表示一個像素;

要将 1 位色轉換成 8 位色,需要将一個位元組逐位分拆并将其填充成一個位元組,如下圖所示:

/LGC圖形渲染/常見顔色深度的 bitmap 之間的互相轉換
圖4

實作代碼如下所示:

for (row = 0;row < src_buffer_height; row++) {

        sp = src_buf + src_buf_pitch * row;

	dp = dst_buf + dst_buf_pitch * row;



        for (col = 0; col < src_buffer_width; col++) {

                bit = col %8;

                if (bit == 0)

                c = *sp++;

                *dp++ = (c >> bit) & 0x01;

        }

}



      

繼續閱讀