CImage 访问像素点 像素数据操作

在CImage类的像素访问

MSDN的代码

COLORREF pixel;
   int maxY = imgOriginal.GetHeight(), maxX = imgOriginal.GetWidth();
   byte r,g,b,avg;
   for (int y=0; y<maxY; y++) {
    for (int x=0; x<maxX; x++) {
     pixel = imgOriginal.GetPixel(x,y);
     r = GetRValue(pixel);
     g = GetGValue(pixel);
     b = GetBValue(pixel);
     avg = (r+ g+ b)/3;
     imgOriginal.SetPixelRGB(x,y,avg,avg,avg);
}}

这种方式效率很低, 因为每次调用getpixel,都包含着程序的进栈和出栈。所以,面对大量需要处理的数据,采用直接访问内存地址的方法。

byte* pRealData;
   pRealData=(byte*)imgOriginal.GetBits();
   int pit=imgOriginal.GetPitch();
   int bitCount=imgOriginal.GetBPP()/8;
   for (int y=0; y<maxY; y++) {
    for (int x=0; x<maxX; x++) {
int grayVal=(int)(int)(*(pRealData + pit*y + x*bitCount))*0.3
      +
      (int)(int)(*(pRealData + pit*y + x*bitCount +1))*0.59
      +
      (int)(int)(*(pRealData + pit*y + x*bitCount +2))*0.11;
     *(pRealData + pit*y + x*bitCount)=grayVal;
     *(pRealData + pit*y + x*bitCount +1)=grayVal;
     *(pRealData + pit*y + x*bitCount +2)=grayVal;
//如果是8位灰度图像,直接读取一个BYTE位为灰度值
//如果是24位RGB图像,则依次读取pixAddr,pixAddr+1,pixAddr+2为B、G、R分量值
}}

用两种方法对同一张图片(3264*2448像素)进行处理,前者需要1分钟,后者只需1秒左右。

所以,后者比前者至少快60倍。

还有一种处理方式

//真彩色图像变为灰度图,直接修改像素点的值

void PixelsChangedToGray(CImage *pImage)
{
 	int		nByte,j,i,nWidth,nHeight,nBytesPerPixel;
	BYTE	*pPixelLine,cNewPixelValue;
	nWidth=pImage->GetWidth();	nHeight=pImage->GetHeight();
	nBytesPerPixel= pImage->GetBPP()/8;
	for (i=0;i<nHeight;i++){
	    pPixelLine =(BYTE*) pImage->GetPixelAddress(0,i);
	    nByte=0;
	    for (j=0;j<nWidth;j++){ 		cNewPixelValue=(BYTE)(0.11*pPixelLine[nByte]
                                                        +0.59*pPixelLine[nByte+1]
                                                        +0.30*pPixelLine[nByte+2]);
		pPixelLine[nByte] = pPixelLine[nByte+1] = pPixelLine[nByte+2]
                        = cNewPixelValue;
		nByte+=nBytesPerPixel;
	    }  
	}
}


//非真彩色图像变为灰度图,修改调色板信息

void PaletteChangedToGray(CImage *pImage)
{
 	RGBQUAD	ColorTabs[256];
 	int		i,nColorTableEntries,nNewGrayColor;
	nColorTableEntries=pImage->GetMaxColorTableEntries();
 	pImage->GetColorTable(0,nColorTableEntries,ColorTabs);
	for (i=0;i<nColorTableEntries;i++){
	    nNewGrayColor=(int)(0.11*ColorTabs[i].rgbBlue
                                           + 0.59*ColorTabs[i].rgbGreen 
                                           + 0.30*ColorTabs[i].rgbRed);
	    ColorTabs[i].rgbBlue = (BYTE)nNewGrayColor;
	    ColorTabs[i].rgbGreen = (BYTE)nNewGrayColor;
	    ColorTabs[i].rgbRed = (BYTE)nNewGrayColor;    
	}
	pImage->SetColorTable(0,nColorTableEntries,ColorTabs);
}


本博客所有博文,若无专门说明皆为原创,转载请注明作者和出处!
原文地址:https://www.cnblogs.com/ifinver/p/2828695.html