您的位置:首页 > 其它

CImage访问像素及其像素操作总结

2014-10-19 22:15 141 查看

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倍

直接访问内存地址的另一种方式:

int i,j,temp;
int pixel[4];
int width = yuantu.GetWidth();
int height = yuantu.GetHeight();
int widthBytes = yuantu.GetPitch();
bianyuantu.Create(width,height,yuantu.GetBPP());

if(yuantu.IsIndexed())
{
yuantu.GetColorTable(0,256,colorTable);
bianyuantu.SetColorTable(0,256,colorTable);
}
BYTE *pYuantuData = (BYTE*)yuantu.GetBits();
BYTE *pBianyuantuData =(BYTE*)bianyuantu.GetBits();

for(j=0;j<height-1;j++)
{
for(i=0;i<width-1;i++)
{
pixel[0]=pYuantuData[j*widthBytes+i];
pixel[1]=pYuantuData[j*widthBytes+i+1];
pixel[2]=pYuantuData[(j+1)*widthBytes+i];
pixel[3]=pYuantuData[(j+1)*widthBytes+i+1];
temp=(int)sqrt((double)((pixel[0]-pixel[3])*(pixel[0]-pixel[3])
+(pixel[1]-pixel[2])*(pixel[1]-pixel[2]))); //罗伯特算子
pBianyuantuData[j*widthBytes+i]=temp;
}
}


  

彩色图像转化为灰度图的处理方式

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

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: