将8位位图转为24位显示为什么常常导致图像显示变形 现在位图一般都是8位和24位的,因此在读入图像处理时总想8位的作为24位来显示,从而绕过调色板这一层,便于统一处理,但为什么8位转为24位显示时有的图像(宽度为偶数)正常,有的则变形,请高手指点一二,谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这个问题这几天我也遇到过,郁闷了好几天。经过几天的思考和高人指点,有了点头绪。不敢独享,就和大家讨论一下。bmp图片的格式有一个要求:就是一行的字节数必须是4的倍数(我只知道必须这样,但我不知道为什么这样,而且我觉得这样很不方便,没有必要)。比如WIDTH=150,在24位的图片中,一行的字节数应该是150*3=450,可是450不是4的倍数,所以要变成452。同时,8位的情况下,150也不是4的倍数,也应该变成152,所以当你在做8位和24位之间变换的时候,就会出现问题了(152*3!=452)。我想图象变形的原因就在这吧。很显然,如果图象的宽度是4的倍数,这样的情况就不会出现。要解决这个问题,你可以用以下的代码(来自CSDN上其他网友的帖子)看看这个帖子。http://expert.csdn.net/Expert/topic/1809/1809709.xml?temp=.155987 读数据也没有问题,我上面写错了,其实对于行宽为奇数的图像有的也可以正常打开显示,但有的就不行,为了说清楚点,我把这段代码贴过来 HANDLE stream; BITMAPFILEHEADER Bmp_file_head; unsigned char* lpbitsrc; BITMAPINFO *lpbitmap; int size; int BitCount; unsigned long dwNotUsed; stream = CreateFile (lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if( stream == INVALID_HANDLE_VALUE ) return FALSE; ReadFile(stream,&Bmp_file_head,sizeof(BITMAPFILEHEADER),&dwNotUsed,NULL); if(Bmp_file_head.bfType!=0x4d42) { AfxMessageBox("图象文件不是位图!"); return FALSE; } size=Bmp_file_head.bfOffBits-sizeof(BITMAPFILEHEADER); lpbitmap=(BITMAPINFO *) new BYTE[size]; ReadFile(stream,lpbitmap,size,&dwNotUsed,NULL); BitCount=lpbitmap->bmiHeader.biBitCount; size=Bmp_file_head.bfSize-Bmp_file_head.bfOffBits; lpbitsrc=new BYTE[size]; ReadFile (stream,lpbitsrc,size,&dwNotUsed,NULL); CloseHandle (stream); int Width,Height; Width=lpbitmap->bmiHeader.biWidth; Height=lpbitmap->bmiHeader.biHeight; size = WIDTHBYTES(Width*24)*Height; pData=new BYTE[size]; ASSERT(pData != NULL); int i,j; int tempWidth; int temp; if(BitCount==24) memcpy(pData,lpbitsrc,size); if(BitCount==8) { tempWidth=WIDTHBYTES(8*Width); for(i=0;i<Height;i++) for(j=0;j<Width;j++) { temp=lpbitsrc[i*tempWidth+j]; pData[(i*Width+j)*3]=lpbitmap->bmiColors[temp].rgbBlue; pData[(i*Width+j)*3+1]=lpbitmap->bmiColors[temp].rgbGreen; pData[(i*Width+j)*3+2]=lpbitmap->bmiColors[temp].rgbRed; } } delete lpbitmap; delete lpbitsrc;WIDTHBYTES()宏是用来对行字节取4倍数变换的,pData就是最后要显示的数据,显示时我自己做个24位的信息头就行了 pData[(i*Width+j)*3]有问题。这样试试:newLineBytes=WIDTHBYTES(Width*24);pData[i*newLineBytes+j*3]=... bmp图片一个扫描行的字节数必须是4的倍数,应该就是这个了。 如何正确输出UBYTE类型的内容 从今天开始,再次拜师学艺.散分给前20位 谁能告诉我怎么用 NDIS-HOOK 实现ICMP 包的过滤 600分 相谢! ★★★高分求有关地理信息系统的电子书、课件等资料★★★ 如何从COM口读数据? MFC如何编写去噪的程序 如何在vc程序中备份还原sqlserver数据库???????[在线等待]. 菜鸟问题!!————高手请闲庭信步 谁有有关坐标转换的代码?帮帮忙吧! 区分左右点 算法请教 求救数据截取方法!从仪器读出数据为(0.00,20.3 ),如何取出20.3这个数!
bmp图片的格式有一个要求:就是一行的字节数必须是4的倍数(我只知道必须这样,但我不知道为什么这样,而且我觉得这样很不方便,没有必要)。比如WIDTH=150,在24位的图片中,一行的字节数应该是150*3=450,可是450不是4的倍数,所以要变成452。同时,8位的情况下,150也不是4的倍数,也应该变成152,所以当你在做8位和24位之间变换的时候,就会出现问题了(152*3!=452)。
我想图象变形的原因就在这吧。很显然,如果图象的宽度是4的倍数,这样的情况就不会出现。要解决这个问题,你可以用以下的代码(来自CSDN上其他网友的帖子)
看看这个帖子。http://expert.csdn.net/Expert/topic/1809/1809709.xml?temp=.155987
HANDLE stream;
BITMAPFILEHEADER Bmp_file_head;
unsigned char* lpbitsrc;
BITMAPINFO *lpbitmap;
int size;
int BitCount;
unsigned long dwNotUsed; stream = CreateFile (lpFileName,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if( stream == INVALID_HANDLE_VALUE )
return FALSE; ReadFile(stream,&Bmp_file_head,sizeof(BITMAPFILEHEADER),&dwNotUsed,NULL);
if(Bmp_file_head.bfType!=0x4d42)
{
AfxMessageBox("图象文件不是位图!");
return FALSE;
} size=Bmp_file_head.bfOffBits-sizeof(BITMAPFILEHEADER);
lpbitmap=(BITMAPINFO *) new BYTE[size];
ReadFile(stream,lpbitmap,size,&dwNotUsed,NULL);
BitCount=lpbitmap->bmiHeader.biBitCount;
size=Bmp_file_head.bfSize-Bmp_file_head.bfOffBits;
lpbitsrc=new BYTE[size];
ReadFile (stream,lpbitsrc,size,&dwNotUsed,NULL);
CloseHandle (stream);
int Width,Height;
Width=lpbitmap->bmiHeader.biWidth;
Height=lpbitmap->bmiHeader.biHeight;
size = WIDTHBYTES(Width*24)*Height;
pData=new BYTE[size];
ASSERT(pData != NULL);
int i,j;
int tempWidth;
int temp;
if(BitCount==24)
memcpy(pData,lpbitsrc,size);
if(BitCount==8)
{
tempWidth=WIDTHBYTES(8*Width);
for(i=0;i<Height;i++)
for(j=0;j<Width;j++)
{
temp=lpbitsrc[i*tempWidth+j];
pData[(i*Width+j)*3]=lpbitmap->bmiColors[temp].rgbBlue;
pData[(i*Width+j)*3+1]=lpbitmap->bmiColors[temp].rgbGreen;
pData[(i*Width+j)*3+2]=lpbitmap->bmiColors[temp].rgbRed;
}
}
delete lpbitmap;
delete lpbitsrc;
WIDTHBYTES()宏是用来对行字节取4倍数变换的,pData就是最后要显示的数据,显示时我自己做个24位的信息头就行了
这样试试:newLineBytes=WIDTHBYTES(Width*24);
pData[i*newLineBytes+j*3]=...