将RGB彩色图像转为8位的索引颜色
先定义一个宏
// Greyscale conversion
#define GREY(r, g, b) (BYTE)(((WORD)r * 77 + (WORD)g * 150 + (WORD)b * 29) >> 8
//#define GREY(r, g, b) (BYTE)(((WORD)r * 169 + (WORD)g * 256 + (WORD)b * 87) >> 9)
// Grayscale, 将RGB转为8bit
void GDIPlusImage::IPFuncGrayscale()
{Bitmap* ima = this->m_pBitmap;if (!ima) {return;}// Build new 8bpp greyscale bitmapint width = ima->GetWidth();int height = ima->GetHeight();Rect rect(0, 0, width, height);BitmapData bitmapData_org, bitmapData_new;Bitmap *pGrayImg = new Bitmap(width, height,PixelFormat8bppIndexed); ColorPalette *pal = (ColorPalette *)malloc(sizeof(ColorPalette)+256*sizeof(ARGB));pal->Count = 256;pal->Flags = 2;for (int i = 0; i < 256; i++){pal->Entries[i] = Color::MakeARGB(255,i,i,i);}pGrayImg->SetPalette(pal);pGrayImg->LockBits(&rect,ImageLockModeWrite,PixelFormat8bppIndexed,&bitmapData_new); //锁定位图,然后对其进行读写内存操作,相关信息保存到BitmapData中Status iSucess = ima->LockBits(&rect,ImageLockModeRead | ImageLockModeWrite,ima->GetPixelFormat() ,&bitmapData_org);BYTE *_pixels = (BYTE*)bitmapData_org.Scan0; //原图rect区域内存位置的起始指针,以BYTE作为单元类型BYTE *_newpixles = (BYTE*)bitmapData_new.Scan0; //目标位图rect区域的起始指针BYTE _grey;// build pixlesswitch(ima->GetPixelFormat()) //像素格式不同,灰度化处理方式也不同{case PixelFormat24bppRGB:{int _strideoff24 = bitmapData_org.Stride - 3*width;int _strideoff8 = bitmapData_new.Stride - width;// 灰度化for (int i=0; i < height; i++){for (int j=0;j < width;j++){ BYTE* _pixels_b; //bBYTE* _pixels_g; //gBYTE* _pixels_r; //r_pixels_b = _pixels++; //blue_pixels_g = _pixels++; //green_pixels_r = _pixels++; //red_grey = GREY(*_pixels_r, *_pixels_g, *_pixels_b); *_newpixles = _grey; //根据红绿蓝求出此像素的灰度值_newpixles += 1;}_pixels += _strideoff24;_newpixles += _strideoff8;}}break;case PixelFormat32bppARGB:{int _strideoff32 = bitmapData_org.Stride - 4*width;int _strideoff8 = bitmapData_new.Stride - width;// 灰度化for (int i=0;i<height;i++){for (int j=0;j<width;j++){ BYTE* _pixels_b;BYTE* _pixels_g; BYTE* _pixels_r; _pixels_b = _pixels++; //blue_pixels_g = _pixels++; //green_pixels_r = _pixels++; //red_grey = GREY(*_pixels_r, *_pixels_g, *_pixels_b); *_newpixles = _grey;_pixels ++; //忽略alpha位置_newpixles += 1;}_pixels += _strideoff32;_newpixles += _strideoff8;}}break;case PixelFormat8bppIndexed: // 因为比Clone(rect,ima->GetPixelFormat())要快{// 直接复制memcpy(_newpixles, _pixels, height * bitmapData_new.Stride);}break;default:break;}ima->UnlockBits(&bitmapData_org);pGrayImg->UnlockBits(&bitmapData_new);free (pal); // 释放掉malloc开辟的空间m_pBitmap = pGrayImg;
}