CImage类库是一个优秀的图像操作类库。而本文主要讲的是利用CIMAGE库的GetBits函数提取的图片像素的资料到图片矩阵中去!
一维数组储存:
在CImage类中,对像素访问最方便的是用GetPixel,MSDN中给出的例子simpleImage的代码如下:发现执行速度特别慢。
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); //GetRValue就是指得到pixel的red值
g = GetGValue(pixel);
b = GetBValue(pixel);
avg = (r+ g+ b)/3;
imgOriginal.SetPixelRGB(x,y,avg,avg,avg);
}
}
发现执行速度特别慢。因为每次调用getpixel,都包含程序的进筏出筏//函数参数传递。所以,面对大量需要处理的数据,采用直接访问内存地址的方法。
byte* pRealData;byte* pRealData1;byte* pRealData2;byte* pRealData3;
pRealData=(byte*)imgOriginal.GetBits();
int pit=imgOriginal.GetPitch();//图像每行字节数
int bitCount=imgOriginal.GetBPP()/8;//获取每像素的位数~~/8得到字节数
for (int y=0; y<maxY; y++)
{
for (int x=0; x<maxX; x++)
{
*(pRealData1+ pit*y + x)=(int)(int)(*(pRealData + pit*y + x*bitCount));
*(pRealData2+ pit*y + x)=(int)(int)(*(pRealData + pit*y + x*bitCount +1));
*(pRealData3+ pit*y + x)=(int)(int)(*(pRealData + pit*y + x*bitCount +2));
//如果是8位灰度图像,直接读取一个BYTE位为灰度值
//如果是24位RGB图像,则依次读取pixAddr,pixAddr+1,pixAddr+2为B、G、R分量值
}
}
用两种方法对同一张图片(3264*2448像素)进行处理,前者需要1分钟,后者只需1秒左右。所以,后者比前者至少快60倍。
二维数组储存:
int width = m_pImage->GetWidth();
int height = m_pImage->GetHeight();
int BytesPerLine = (width + 3) / 4 * 4; // 只对8位图像
BYTE *pDib = m_pImage->GetBits();
for (int row = 0; row < height; row++)
{
for (int column = 0; column < width; column++)
{
m_pPixelMatrix[row][column] = *(pDib + (height - 1 - row * BytesPerLine + column);
}
}