在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);
}