CPalette是MFC封装的调色板类。CPalette的操作如下: 1. 创建调色板。要创建一个调色板,需要首先知道要创建的调色板对象所包含的颜色数nColors,然后创建一个逻辑调色板
LOGPALETTE结构,并利用该逻辑调色板结构初始化调色板对象。 UINT nSize=sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY)*(nColors-1)); //计算逻辑调色板所需空间 LOGPALETTE *pLP=(LOGPALETTE*) new BYTE[nSize]; //初始化逻辑调色板,假设R,G,B 保存的是调色板各颜色红,绿,蓝三个分量的数组 pLP->palVersion=0x300; //固定值 pLP->palNumEntries=nColors; for(int i=0;i<nColors;i++) { pLP->palPalEntry[i].peRed=R[i]; pLP->palPalEntry[i].peGreen=G[i]; pLP->palPalEntry[i].peBlue=B[i]; pLP->palPalEntry[i].peFlags=0; } //创建调色板 CPalette m_palette; m_palette.CreatePalette(pLP); 2.从位图创建调试版。假设m_bitmap是一个CBitmap对象。 DIBSECTION ds; m_bitmap.GetObject(sizeof(DIBSECTION),&ds);
//计算颜色数 int nColors; if(ds.dsBmih.biClrUsed!=0) { nColors=ds.dsBmih.biClrUsed; } else { nColors=1<<ds.dsBmih.biBitCount; }
//创建调色板 if(nColors>256) m_palette.CreateHalftonePalette(&dc); else { RGBQUAD *pRGB=new RGBQUAD[nColors];
//得到位图颜色列表 CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap *pOldBitmap=memDC.SelectObject(&m_bitmap); ::GetDIBColorTable((HDC)memDC,0,nColors,pRGB); //得到颜色列表 memDC.SelectObject(pOldBitmap);
//初始化逻辑调色板 UINT nSize=sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY)*(nColors-1)); LOGPALETTE *pLP=(LOGPALETTE*) new BYTE[nSize]; pLP->palVersion=0x300; pLP->palNumEntries=nColors; for(int i=0;i<nColors;i++) { pLP->palPalEntry[i].peRed=pRGB[i].rgbRed; pLP->palPalEntry[i].peGreen=pRGB[i].rgbGreen; pLP->palPalEntry[i].peBlue=pRGB[i].rgbBlue; pLP->palPalEntry[i].peFlags=0; }
//创建调色板 m_palette.CreatePalette(pLP); }
3.使用调色板: 要使用以创建好的调试版m_palette,需要在画图前选如调色板,并实现之。 CPalette *pOldPalette=pDC->SelectPalette(&m_palette,FALSE); pDC->RealizePalette(); ... //图像显示或画图操作 pDC->SelectPalette(pOldPalette,FALSE);
CBitmap是MFC封装的一个位图类,这个位图可以使DDB或DIB,即设备相关位图或设备无关位图。
关于CBitmap的操作如下:
1. 位图读取。如果从文件读取一幅位图并保持在m_bitmap对象中,操作如下:
HBITMAP hBitmap; hBitmap=(HBITMAP)::LoadImag (NULL, lpszPathName, IMAGE_BITMAP, 0,0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION); if(!hBitmap) m_bitmap.Attach(hBitmap); 如果从资源载入一幅位图直接用m_bitmap.LoadBitmap( nIDResource ); 2.位图显示。首先如果位图有调色板,把位图调色板选人DC并实现之 CPalette *pOldPalette=pDC->SelectPalette(pPalette,FALSE); pDC->RealizePalette(); 然后再用BitBlt或StretchBlt显示 CDC* memDC; memDC->CreateCompatibleDC(pDC); CBitmap *pOldBitmap=memDC->SelectObject(&m_bitmap); pDC->BitBlt(0,0,bitmapWidth,bitmapHeight, &memDC,0,0,SRCCOPY); //显示图像
DIB又叫设备无关位图,顾名思义,像素的颜色独立于系统调色板,因此可以用来在不同的系统之间或不同的应用程序之间交流,或永久性地保存图象。 DIB文件是以BITMAPFILEHEADER结构开头的,紧随该结构的是一个BITMAPINFOHEADER结构,然后是RGBQUAD结构组成的颜色表(对于2、8、16、256色位图而言,24位真彩色位图没有),文件最后存储的是DIB的像素阵列。BITMAPFILEHEADER结构的定义为: typedef struct tagBITMAPFILEHEADER { WORD bfType; //文件类型,必须为"BM" DWORD bfSize; //文件的大小 WORD bfReserved1; //为0 WORD bfReserved2; //为0 DWORD bfOffBits; //存储的像素阵列相对于文件头的偏移量 } BITMAPFILEHEADER; 在内存中,一个完整的DIB由两部分组成:一个BITMAPINFO结构和一个存储像素阵列的数组。BITMAPINFO 描述了位图的大小,颜色模式和调色板等各种属性,其定义为: typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; //颜色列表,在此只是占位,如果位图没有颜色列表,该数组为空。 } BITMAPINFO; 其中BITMAPINFOHEADER结构包含了DIB的各种信息,其定义为: typedef struct tagBITMAPINFOHEADER { DWORD biSize; //该结构的大小 LONG biWidth; //位图的宽度(以像素为单位) LONG biHeight; //位图的高度(以像素为单位) WORD biPlanes; //必须为1 WORD biBitCount //每个像素的位数(1、4、8、16、24或32) DWORD biCompression; //压缩方式,一般为0或BI_RGB (未压缩) DWORD biSizeImage; //以字节为单位的图象大小(仅用于压缩位图) LONG biXPelsPerMeter; //以目标设备每米的像素数来说明位图的水平分辨率 LONG biYPelsPerMeter; //以目标设备每米的像素数来说明位图的垂直分辨率 DWORD biClrUsed; //颜色表的颜色数,若为0则位图使用由biBitCount指定的最大颜色数 DWORD biClrImportant; //重要颜色的数目,若该值为0则所有颜色都重要 } BITMAPINFOHEADER; RGBQUAD结构用来描述颜色,其定义为: typedef struct tagRGBQUAD { BYTE rgbBlue; //蓝色分量 BYTE rgbGreen; //绿色分量 BYTE rgbRed; //红色分量 BYTE rgbReserved; //保留字节,为0 } RGBQUAD; DIB的字节数组是从图象的最下面一行开始的逐行向上存储的,也即等于把图象倒过来然后在逐行扫描。另外,字节数组中每个扫描行的字节数必需是4的倍数,如果不足要用0补齐。