p
* 功 能: 实现bmp格式灰度图片的平移,移出部分用白色填充
*/
#include
#include
#include
#include
using namespace std;
BITMAPFILEHEADER bmpFileHeader; //位图文件头
BITMAPINFOHEADER bmpInfoHeader; //位图信息头
RGBQUAD *pColorTable = new RGBQUAD[256]; //颜色表指针
unsigned char *pBmpData; //图像数据指针
unsigned char *pBmpData1; //平移后图像数据指针
unsigned char *pTemp,*pTemp1; //临时指针
int width,height,imgSize; //图像宽,高,实际大小,imgSize必须为4的倍数,bmp格式文件结构规定
int srcX[2],srcY[2],dstX[2],dstY[2]; //平移前后位置
/**
* 函数名: readBmp
* 参 数: bmpFileName--指向读入bmp文件的文件名指针
* 功 能: 读入一个bmp文件,获得相应数据
*/
bool readBmp(char *bmpFileName)
{
FILE *fp = fopen(bmpFileName,"rb"); //以二进制读方式打开指定的图像文件
if(NULL == fp)
{
printf("%s is not exist!",bmpFileName);
return FALSE;
}
fread(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); //读取位图头信息放入bmpFileHeader,注:指针也相应移动
fread(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp); //读取位图信息头放入bmpInfoHeader
width = bmpInfoHeader.biWidth; //宽
height = bmpInfoHeader.biHeight; //高
fread(pColorTable,sizeof(RGBQUAD),256,fp); //读取颜色表放入pColorTable
// int bytePerLine = (bmpInfoHeader.biWidth * bmpInfoHeader.biBitCount + 31) / 32 * 4;
pBmpData = new unsigned char [imgSize = bmpInfoHeader.biSizeImage];
pBmpData1 = new unsigned char [imgSize];
memset(pBmpData1,(BYTE)255,sizeof(char)*imgSize); //把新的图像信息用255(白色)填充,平移后没有图像的区域就是白色了
fread(pBmpData,sizeof(char),bmpInfoHeader.biSizeImage,fp); //读取图像信息放入pBmpData
fclose(fp); //记住要关闭文件
return TRUE;
}
/**
* 函数名: translation
* 参 数: tx--平移的x距离,ty--平移的y距离
* 功 能: 实现平移,并把平移后图像信息写入pBmpData1
*/
void translation(int tx,int ty)
{
bool xVisible = TRUE,yVisible = TRUE;
//xVisible为FALSE时,表示x方向已经移出了可显示的范围
if(tx <= -width)
{
xVisible = FALSE;
}
else if(tx <= 0)
{
dstX[0] = 0; //表示移动后,有图区域的左上角点的x坐标
dstX[1] = width + tx; //表示移动后,有图区域的右下角点的x坐标
}
else if(tx < width)
{
dstX[0] = tx;
dstX[1] = width;
}
else
xVisible = FALSE;
srcX[0] = dstX[0] - tx; //对应DstX0在原图中的x坐标
srcX[1] = dstX[1] - tx; //对应DstX1在原图中的x坐标
int rectWidth = srcX[1] - srcX[0]; //有图区域的宽度
//y的和x类似,就不加注释了
if(ty <= -height)
yVisible = FALSE;
else if(ty <= 0)
{
dstY[0] = 0;
dstY[1] = height + ty;
}
else if(ty < height)
{
dstY[0] = ty;
dstY[1] = height;
}
else
yVisible = FALSE;
srcY[0] = dstY[0] - ty;
srcY[1] = dstY[1] - ty;
int rectHeight = srcY[1] - srcY[0];
int lineBytes = (width * bmpInfoHeader.biBitCount + 31) / 32 * 4; //每行所占的字节数,必须为4的倍数
if(xVisible && yVisible)
{
for(int i = 0; i < rectHeight; i++ )
{
//pTemp指向要拷贝的那一行的最左边的象素对应在原图中的位
//置。特别要注意的是,由于.bmp是上下颠倒的,
pTemp = pBmpData + (height - 1 - (srcY[0] + i)) * lineBytes + srcX[0];
//pTemp1指向要拷贝的那一行的最左边的象素对应在新图中的位置。同样要注意上面的问题。
pTemp1 = pBmpData1 + (height - 1 - (dstY[0] + i)) * lineBytes + dstX[0];
memcpy(pTemp1,pTemp,rectWidth); //从pTemp中复制大小