C++BMP32位转24位,当图像宽度不是4的倍数时转换出错,求修改最后写入部分。 20

voidCDib::Bmp32ToBmp24(charFilename[]){char*szStr;char*Filename2={""};Filename2=Filen... void CDib::Bmp32ToBmp24(char Filename[])
{
char* szStr;
char *Filename2 = { "" };
Filename2 = Filename;
szStr = Filename;

HBITMAP hbmp32 = (HBITMAP)LoadImage(NULL, szStr,

IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE |
LR_CREATEDIBSECTION);
BITMAP bmp;//获取位图信息
GetObject(hbmp32, sizeof(BITMAP), &bmp);
int BytesPerLine = 3 * bmp.bmWidth;

while (BytesPerLine % 4 != 0)
BytesPerLine++;
BITMAPINFOHEADER bih = { 0 };//位图信息头
bih.biBitCount = 24;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = BytesPerLine * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度
BITMAPFILEHEADER bfh = { 0 };//位图文件头

bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;//文件总的大小
bfh.bfType = (WORD)0x4d42;
FILE *fp = fopen(Filename2, "w+b");

fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头

fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头

byte * p = new byte[bih.biSizeImage];

//获取当前32位图像数据

GetDIBits(GetDC(NULL), hbmp32, 0, bmp.bmHeight, p, (LPBITMAPINFO)&bih, DIB_RGB_COLORS);

//只取rgb值,存入文件
BYTE b = 0;//用于填充
for (int i = 0; i < bmp.bmWidth * bmp.bmHeight; i++)
{
//32位位图图像的格式为:Blue, Green, Red, Alpha
fwrite(&(p[i * 3]), 1, 3, fp);
if (i % bmp.bmWidth == bmp.bmWidth - 1)//填充字节
{
for (int k = 0; k < (BytesPerLine - bmp.bmWidth * 3 ); k++)
fwrite(&b, sizeof(BYTE), 1, fp);
//fwrite(&b, 1, 1, fp);
}
}
delete[] p;

fclose(fp);

DeleteObject(hbmp32);
}
展开
 我来答
Getline
2014-02-23 · 科技领域创作者
Getline
采纳数:405 获赞数:2705

向TA提问 私信TA
展开全部
这跟你图像宽度应该没有任何关系啊,应该跟linebytes有关。24位是3个byte表示一个点,32位是4个byte表示一个点。另外32位图,高位才是alpha通道吧?大周末的懒的看代码,你自己再看看吧。
追问
你说的没错,是和linebytes有关,即使输入的宽度不是4的倍数,linebytes也会自动加成4的倍数,但是后面的代码,我是指for (int k = 0; k < (BytesPerLine - bmp.bmWidth * 3 ); k++)
fwrite(&b, sizeof(BYTE), 1, fp);有问题,当宽度不为4的倍数的时候,图像就会失真!
追答
写的时候别一个byte一个byte的写,注意字节对齐问题。或者设置编译器字节对齐为1.
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式