首页 > 其他分享 >GDIPlus灰度化图像

GDIPlus灰度化图像

时间:2022-12-13 16:03:57浏览次数:38  
标签:ima int bitmapData ++ GDIPlus 灰度 图像 BYTE pixels


将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 bitmap
int 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 pixles
switch(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; //b
BYTE* _pixels_g; //g
BYTE* _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;
}



标签:ima,int,bitmapData,++,GDIPlus,灰度,图像,BYTE,pixels
From: https://blog.51cto.com/u_15911341/5934369

相关文章