把最近看的整理一下。
视频旋转照我的理解就是处理图像中的unsigned char指针所指的数据点,现在的思路是对RGB图像进行旋转,但是旋转之前,我们应该要先获得RGB图像点的数据结;
RGB图像数据的存储是一个像素点占三个字节,也就是说二个像素点(x1,y1),(x1,y1),那么它们的像素值分别是B0,G0,R0,B1,G1,R1。这六个值花占六个字节,而且是连接存放在一片内存空间。那么,要怎么了获得每个像素点的RGB呢?
首先,我们得知道图像每行的字节数
一、图像每行字节数的计算
方法一:.利用宏:#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
方法二: (nImageWidth*nBitCount+31)/32*4;
nImageWidth为图像宽度;nBitCount为每个像素所占的位数,如:二值为1,灰度为8,真彩24
方法三: (mImageWidth * (mImageBitCount / 8) + 3) & ~3
方法一说明:这里有一个宏,可以很方便的算出这个字节数:#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4),使用方法如下:long lLineBytes = WIDTHBYTES(m_lWidth * 24)。如果是8位的bmp图像,或4位,2位,则将算式中的24改为相应的位数即可。另外bmp文件分文件头14字节,信息40字节,调色板若干字节,数据lLineBytes*height字节。
注意:bmp文件的数据块部分不是直接的一个个像素排列后存储。为了要保证每行的字节数都能够被4整除,往往要在每行数据后面补充1,2或3个字节的冗余信息。
X*Y大小的24位bmp图像,每个像素占3个字节,如果X*3后不能够被4整除,则每行有可能是X*3+1, X*3+2或X*3+3, 取决于哪个数值可以被4整除。
二、访问图像中特定的一个第x行,第y列的像素
假设文件的起始位置是图像的左上角,像素依次从左向右,从上到下排列。
假设指向文件的数据区的指针byte* p_bmpdata, 文件为24位,为了访问第x行,第y列,可以用如下公式:
b = p_bmpdata[lLineBytes * x + y*3];
g = p_bmpdata[lLineBytes *x + y*3+1];
r = p_bmpdata[lLineBytes * x + y*3+2];
如果要从第一个像素开始遍历整个数据区,可以用这样的方式:
for (i = 0; i <height; i ++)
{
for (j = 0; j < width; j ++)
{
b = p_bmpdata[lLineBytes * i + j*3];
g = p_bmpdata[lLineBytes * i + j*3+1];
r = p_bmpdata[lLineBytes * i + j*3+2];
}
}
注意,这里的height和width是图像的列像素数和行像素数。而循环内与i相乘的是整行的字节数,不是行像素数。
三、建立图像缓冲区
当使用自己建立的图像缓冲区是,遍历的方法又有所不同。假设为上bmp文件的数据作一个缓冲。
byte *p_bmpbuffer = new byte[height*width*3];
for(i = 0; i< width; i++)
{
for(j=0; j<height; j++)
{
p_bmpbuffer[(i*height+j)*3] = p_bmpdata[lLineBytes * i + j*3];
p_bmpbuffer[(i*height+j)*3+1] = p_bmpdata[lLineBytes * i + j*3+1];
p_bmpbuffer[(i*height+j)*3+2] = p_bmpdata[lLineBytes * i + j*3+2];
}
}
//这里不用memcpy的原因是p_bmpdata的长度为height*lLineBytes, 而p_bmpbuffer的长度是height*width*3, p_bmpdata在每行末都有1,2或3个字节的冗余。
byte b, g, r;
for(i = 0; i< height; i++)
{
for(j=0; j<width; j++)
{
b = p_bmpbuffer[(i*width+j)*3];
g = p_bmpbuffer[(i*width+j)*3+1];
r = p_bmpbuffer[(i*width+j)*3+2];
}
}
//这里对像素的访问i,j的意义发生变化,之前的循环顺序访问下来,图像的行被列值y中间截断,虽然可以顺序依次访问每个像素,但i,j值没有实际意义。第二次循环,i值即对应当前像素y坐标,j值对应当前像素x坐标。这样在运用模板滤波时,或是进行相邻像素计算时是准确的。