对BMP文件进行增高并写字时总是失败

red-fly red-fly 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
目的:
对BMP图片的底部增加高度,然后在新增加的区域写字,然后再保存成新的BMP图片。
做法:
根据原始的图片数据创建位图句柄,然后把它显示到内存的DC上,在适当的位置写字(TextOut),然后再获取此DC上的图像数据,接着把此数据保存成为新的BMP图片
限制:
由于这些图片的数据是通过解码视频数据得到的,所以没有所谓的BMP文件头等信息
条件:
纯粹的24位RGB数据

先看代码如下:

BOOL Save2BMPFile(char* FileName, char *RGBData, int RGBDataSize, int width, int height)
{
char *pszTmp = NULL;
char *pTmp = NULL;
HDC dc = CreateDC( TEXT("DISPLAY"), NULL, NULL, NULL );
HDC dc2 = CreateCompatibleDC( dc );

int iCountLine = 1;
long lLineHeight = 20;

long lWidthBytes, lNewHeight;
if(width%4 == 0)
lWidthBytes = width * 3;
else
lWidthBytes = (width+(4-width%4)) * 3;
lNewHeight = height+(iCountLine*lLineHeight);

// 创建新大小的图片内存
pszTmp = new char[lWidthBytes * lNewHeight];
memset( pszTmp, 120,lWidthBytes * lNewHeight);
memcpy(pszTmp + (lWidthBytes * iCountLine*lLineHeight),RGBData,lWidthBytes * height);
pTmp = new char[lWidthBytes];
int l;
for ( l = 0; l < lNewHeight / 2; l++ )
{
memcpy( pTmp, pszTmp + lWidthBytes * l, lWidthBytes );
memcpy( pszTmp + lWidthBytes * l, pszTmp + lWidthBytes * (lNewHeight - 1 - l), lWidthBytes );
memcpy( pszTmp + lWidthBytes * (lNewHeight - 1 - l), pTmp, lWidthBytes );
}

HBITMAP hBitmap = CreateBitmap( width, lNewHeight, 1, 24, pszTmp );
SelectObject( dc2, hBitmap );
l = 0;
TextOut( dc2,5,height, "abc", 3 ); // 在新增加的调试上写个

HBITMAP retBitMap = (HBITMAP)GetCurrentObject(dc2,OBJ_BITMAP);
long lGet = GetBitmapBits(retBitMap,lWidthBytes * lNewHeight,pszTmp);
for ( l = 0; l < lNewHeight / 2; l++ )
{
memcpy( pTmp, pszTmp + lWidthBytes * l, lWidthBytes );
memcpy( pszTmp + lWidthBytes * l, pszTmp + lWidthBytes * (lNewHeight - 1 - l), lWidthBytes );
memcpy( pszTmp + lWidthBytes * (lNewHeight - 1 - l), pTmp, lWidthBytes );
}

// 保存为文件
BITMAPFILEHEADER bmfHdr;
BITMAPINFOHEADER bmiHdr;
ZeroMemory( &bmfHdr, sizeof( bmfHdr ) );
ZeroMemory( &bmiHdr, sizeof( bmiHdr ) );

bmiHdr.biSize = sizeof(BITMAPINFOHEADER);
bmiHdr.biWidth = width;
bmiHdr.biHeight = lNewHeight;
bmiHdr.biPlanes = 1;
bmiHdr.biBitCount = 24;
bmiHdr.biCompression = BI_RGB;
bmiHdr.biSizeImage = 0;
bmiHdr.biXPelsPerMeter = 0;
bmiHdr.biYPelsPerMeter = 0;
bmiHdr.biClrUsed = 0;
bmiHdr.biClrImportant = 0;

bmfHdr.bfType = ((WORD) ('M' << 8) | 'B');
bmfHdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + lWidthBytes*lNewHeight);
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));

FILE *fp;
fp = fopen(FileName,"w+b");
if(fp != NULL)
{
fwrite((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite((LPSTR)&bmiHdr,sizeof(BITMAPINFOHEADER), 1, fp);

int size = lWidthBytes*lNewHeight;
fwrite( pszTmp, lWidthBytes*lNewHeight,1, fp );
fclose(fp);
return TRUE;
}

return FALSE;
}

此函数的几个参数介绍:
FileName:[in],修改后的BMP图片要保存成的文件名
RGBData:[in],原始的BMP图片数据,24位的,不包括文件头等信息,只是纯粹的颜色数据
RGBDataSize:[in],原始数据的长度,单位为字节
width,height:[in],原始图片的宽度和高度,它们的成绩再乘以3应该和RGBDataSize相等

在测试的时候发现总是不对,之前有试过有文件头的就没有问题(只是在拷贝RGBData数据时把文件头去掉,另外在写图片信息时只是更改了和高度有关的信息),但现在总是不对!
请各位大虾帮助
...全文

相关推荐

评论 21
收藏 已收藏
分享
返回顶部
red-fly
界面 15,976 成员 115,866 内容