GDIPlus灰度化图像

将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;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值