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);
} 展开
{
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);
} 展开
1个回答
展开全部
这跟你图像宽度应该没有任何关系啊,应该跟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.
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询