WINVNC是用bitmap格式保存桌面图像的,所以先补充下相关知识。
图像“像素”(Pixel):把影像放大数倍,会发现这些连续色调其实是由许多色彩相近的小方点所组成,这些小方点就是构成影像的最小单位“像素”(Pixel)。
图像分辨率:表示每一个方向上的像素数量,比如640X480,表示由640X480个像素组成。
DPI(Dot Per Inch):表示每英寸显示的像素数。图像显示清晰效果就看这个拉,一英寸等于25.4mm。
位/像素 (bpp:bits per pixel):既每个像素数据需要占用的bit数目,用来保存颜色。比如8位可得到256种颜色,16位可得到65,536种颜色,而24位可得到16,777,216种颜色。
view plain
图像格式一般分为两种:映射图像和向量图像,bitmap就是映射图像。metafile是向量图像。
位映射图像用离散的像素来处理输出设备;而向量图像用笛卡尔座标系统来处理输出设备,其线条和填充对象能被个别拖移。现在大多数的图像输出设备是位映射设备,这包括视讯显示、点阵打印机、激光打印机和喷墨打印机。而笔式绘图机则是向量输出设备。
编辑bitmap大小一般就是复制或删除像素的某些行和列的像素。
view plain
//下面是几个很重要的数据结构
BITMAPFILEHEADER
BITMAPFILEHEADER结构包含关于类型,大小,布局设备无关的位图信息。
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
/*成员
bfType
声明文件类型,必须是BM。
bfSize
声明位图文件的大小,以字节为单位。
bfReserved1
保留,必须为0。
bfReserved2
保留,必须为0。
bfOffBits
声明偏移量,从BITMAPFILEHEADER结构开始到位图数据,以字节为单位。
备注
在设备无关文件中,BITMAPINFOHEADER结构紧随其后。
*/
//BITMAPINFOHEADER
//BITMAPINFOHEADER结构包含设备无关位图的大小以及色彩格式的信息。
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
/*成员
biSize
声明这个结构体所需要的字节数。
biWidth
声明位图的宽,以像素为单位。
biHeight
声明位图的高,以像素为单位。如果biHeight是正数,位图是一个自下而上的设备无关位图,起点在左下角。如果biHeight是负数,位图是一个自上而下的设备无关位图,起点在左上角。
如果biHeight是负数,指示一个自上而下的设备无关位图,biCompression就必须为BI_RGB或者BI_BITFIELDS。自上而下的设备无关位图不能被压缩。
biPlanes
为目标装置声明平面数,这个值必须是1。
biBitCount
声明每像素位数。BITMAPINFOHEADER的成员biBitCount确定了定义每一个像素需要的位数,以及位图所需颜色的最大值。这个成员必须是以下的值:
Value Meaning
0 JPEG或者PNG格式声明每像素位数
1 位图是单色的,包含两个颜色信息,位图数组中的每一位代表一个像素。如果这一位是0,那么这个点的颜色就是调色板中第一个RGBQUAD结构所定义的颜色。如果这一位是1,那么这个点的颜色就是调色板中第二个GBQUAD结构所定义的颜色。
4 位图最多有16种颜色。调色板数组中有16个元素。位图中的每一个像素由一个4位的索引指向调色板。举个例子,位图的第一个字节是0x1F,这个字节代表两个像素,第一个像素颜色是调色板中的第二个RGBQUAD结构所定义的颜色,第二个像素颜色是调色板中的第十六个RGBQUAD结构所定义的颜色。
8 位图最多有256种颜色。调色板中有256个元素。每一个字节代表一个颜色。
16 位图有2^16种颜色。如果biCompression为BI_RGB,则没有调色板。RGB565使用16位表示一个像素,这16位中的5位用于R,6位用于G,5位用于B。 RGB555是另一种16位的RGB格式,RGB分量都用5位表示(剩下的1位不用)。比如从高位到地位:X R R R R G G G G G B B B B B (X表示不用,可以忽略)。
可以组合使用屏蔽字和移位操作来得到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
24 位图最多有2^24种颜色。没有调色板。位图数组中每三个字节代表一个像素的红绿蓝相对强度。
biCompression
BI_RGB:对一种颜色进行编码的方法统称为“颜色空间”或“色域”。用最简单的话说,世界上任何一种颜色的“颜色空间”都可定义成一个固定的数字或变量。RGB(红、绿、蓝)只是众多颜色空间的一种。采用这种编码方法,每种颜色都可用三个变量来表示-红色绿色以及蓝色的强度。RGB1、RGB4、RGB8都是调色板类型的RGB格式,在描述这些媒体类型的格式细节时,通常会在BITMAPINFOHEADER数据结构后面跟着一个调色板(定义一系列颜色)。它们的图像数据并不是真正的颜色值,而是当前像素颜色值在调色板中的索引。以RGB1(2色位图)为例,比如它的调色板中定义的两种颜色值依次为0x000000(黑色)和0xFFFFFF(白色),那么图像数据001101010111…(每个像素用1位表示)表示对应各像素的颜色为:黑黑白白黑白黑白黑白白白…。
biSizeImage
声明图像文件的大小,以字节为单位。如果是BI_RGB位图,可能是0。
biXPelsPerMeter
声明横向点距,以像素每米为单位。
biYPelsPerMeter
声明纵向点距,以像素每米为单位。
biClrUsed
声明实际使用到的颜色个数,如果是0,则使用所有颜色。
biClrImportant
声明显示这个位图必须的颜色索引个数,如果是0,则需要所有颜色。
*/
//RGBQUAD
//RGBQUAD结构描述红绿蓝相对亮度
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
/*成员
rgbBlue
声明蓝色强度
rgbGreen
声明绿色强度
rgbRed
声明红色强度
rgbReserved
保留,必须是0
*/
//我们结合源码看下函数BOOL vncDesktop::SetPixShifts()就能更好的理解它们
view plainview plain
看看函数最后调用的inline void vncDesktop::MaskToMaxAndShift(DWORD mask, CARD16 &max, CARD8 &shift)函数:
view plain
下篇再看看桌面包装类vncDesktop的其它函数。