MFC中CImage类的像素访问

来源:互联网 发布:计算机安全审计软件 编辑:程序博客网 时间:2024/05/01 00:19

在CImage类的像素访问

MSDN的代码

[cpp] view plaincopy
  1. COLORREF pixel;  
  2.    int maxY = imgOriginal.GetHeight(), maxX = imgOriginal.GetWidth();  
  3.    byte r,g,b,avg;  
  4.    for (int y=0; y<maxY; y++) {  
  5.     for (int x=0; x<maxX; x++) {  
  6.      pixel = imgOriginal.GetPixel(x,y);  
  7.      r = GetRValue(pixel);  
  8.      g = GetGValue(pixel);  
  9.      b = GetBValue(pixel);  
  10.      avg = (r+ g+ b)/3;  
  11.      imgOriginal.SetPixelRGB(x,y,avg,avg,avg);  
  12. }}  

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

[cpp] view plaincopy
  1. byte* pRealData;  
  2.    pRealData=(byte*)imgOriginal.GetBits();  
  3.    int pit=imgOriginal.GetPitch();  
  4.    int bitCount=imgOriginal.GetBPP()/8;  
  5.    for (int y=0; y<maxY; y++) {  
  6.     for (int x=0; x<maxX; x++) {  
  7. int grayVal=(int)(int)(*(pRealData + pit*y + x*bitCount))*0.3  
  8.       +  
  9.       (int)(int)(*(pRealData + pit*y + x*bitCount +1))*0.59  
  10.       +  
  11.       (int)(int)(*(pRealData + pit*y + x*bitCount +2))*0.11;  
  12.      *(pRealData + pit*y + x*bitCount)=grayVal;  
  13.      *(pRealData + pit*y + x*bitCount +1)=grayVal;  
  14.      *(pRealData + pit*y + x*bitCount +2)=grayVal;  
  15. //如果是8位灰度图像,直接读取一个BYTE位为灰度值  
  16. //如果是24位RGB图像,则依次读取pixAddr,pixAddr+1,pixAddr+2为B、G、R分量值  
  17. }}  

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

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

还有一种处理方式

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

[cpp] view plaincopy
  1. void PixelsChangedToGray(CImage *pImage)  
  2. {  
  3.     int     nByte,j,i,nWidth,nHeight,nBytesPerPixel;  
  4.     BYTE    *pPixelLine,cNewPixelValue;  
  5.     nWidth=pImage->GetWidth();   nHeight=pImage->GetHeight();  
  6.     nBytesPerPixel= pImage->GetBPP()/8;  
  7.     for (i=0;i<nHeight;i++){  
  8.         pPixelLine =(BYTE*) pImage->GetPixelAddress(0,i);  
  9.         nByte=0;  
  10.         for (j=0;j<nWidth;j++){      cNewPixelValue=(BYTE)(0.11*pPixelLine[nByte]  
  11.                                                         +0.59*pPixelLine[nByte+1]  
  12.                                                         +0.30*pPixelLine[nByte+2]);  
  13.         pPixelLine[nByte] = pPixelLine[nByte+1] = pPixelLine[nByte+2]  
  14.                         = cNewPixelValue;  
  15.         nByte+=nBytesPerPixel;  
  16.         }    
  17.     }  
  18. }  

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

[cpp] view plaincopy
  1. void PaletteChangedToGray(CImage *pImage)  
  2. {  
  3.     RGBQUAD ColorTabs[256];  
  4.     int     i,nColorTableEntries,nNewGrayColor;  
  5.     nColorTableEntries=pImage->GetMaxColorTableEntries();  
  6.     pImage->GetColorTable(0,nColorTableEntries,ColorTabs);  
  7.     for (i=0;i<nColorTableEntries;i++){  
  8.         nNewGrayColor=(int)(0.11*ColorTabs[i].rgbBlue  
  9.                                            + 0.59*ColorTabs[i].rgbGreen   
  10.                                            + 0.30*ColorTabs[i].rgbRed);  
  11.         ColorTabs[i].rgbBlue = (BYTE)nNewGrayColor;  
  12.         ColorTabs[i].rgbGreen = (BYTE)nNewGrayColor;  
  13.         ColorTabs[i].rgbRed = (BYTE)nNewGrayColor;      
  14.     }  
  15.     pImage->SetColorTable(0,nColorTableEntries,ColorTabs);  
  16. }  
0 0
原创粉丝点击