bmp图在XP上显示异常?!求分析! XP BMP BMPXP 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits;} BITMAPFILEHEADER, *PBITMAPFILEHEADER;红的不对 如果是这样的话,win7上所有的显示都是正常的,并且画图显示也是正常的。 而且我确实有考虑了四字节对齐的呀。 ldBmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD); // 数据部分偏移这是我源代码部分。 而且假如这里不对的话,画图程序怎么能正常显示出数据呢 贴上源代码,希望能尽快解决这个问题。用的是pdf417。谢谢了。bool Make2DBarCodeBmp(const wchar_t* nswCodeContent, const wchar_t* nswBmpFile, UINT nuiZoomIn){ if(NULL == nswCodeContent || NULL == nswBmpFile) return false; bool lbRet = false; pdf417param ldPdf417Info = {0}; do { // 构造数据 pdf417init(&ldPdf417Info); ldPdf417Info.text = UnicodeToAnsi(nswCodeContent); ldPdf417Info.options = PDF417_INVERT_BITMAP; paintCode(&ldPdf417Info); if(PDF417_ERROR_SUCCESS != ldPdf417Info.error) { pdf417free(&ldPdf417Info); break; } // ------------------------------------------------------------------------------------------------------------------------------- // 8位位图,一个像素占据一位,方便缩放处理 // ------------------------------------------------------------------------------------------------------------------------------- // 放大倍数 int liZoomInX = nuiZoomIn; int liZoomInY = nuiZoomIn; // 将ldPdf417Info.lenBits中以位为单位的总字节数为ldPdf417Info.outBits的像素值转换成以字节为单位的像素值 ULONG lulPixelWidth = ldPdf417Info.bitColumns * liZoomInX; ULONG lulPixelHeight = ldPdf417Info.codeRows * liZoomInY; ULONG lulBmpWidth = ldPdf417Info.lenBits * 8 / ldPdf417Info.codeRows * liZoomInX; // 因为BMP图存储时数据部分必须四字节对齐,所以Bmp图宽度和像素宽度不一定相同,拷贝数据的时候要以BMP图宽度为准 ULONG lulCbRealDataWithoutRepeatRows = ldPdf417Info.lenBits * 8 * liZoomInX; // 除去了重复行的有效数据字节数 PBYTE lpPixelData = new BYTE[lulCbRealDataWithoutRepeatRows]; // 扩充X倍 RtlZeroMemory(lpPixelData, lulCbRealDataWithoutRepeatRows); // 扩充后的白色像素点数据 ULONG lulRateX = 1 * liZoomInX; // 放大后水平方向上之前每字节对应现在多少个字节 PBYTE lpWhiteColorData = new BYTE[lulRateX]; memset(lpWhiteColorData, 0xFF, lulRateX); BYTE lbBitMask = 0x80; PBYTE lpCrtPos = lpPixelData; for(int i = 0; i < ldPdf417Info.lenBits * 8; ++i) { if(ldPdf417Info.outBits[i / 8] & lbBitMask) { RtlCopyMemory(lpCrtPos, lpWhiteColorData, lulRateX); } lpCrtPos += lulRateX; lbBitMask = lbBitMask >> 1; if(lbBitMask == 0) lbBitMask = 0x80; } SAFE_DELETE(lpWhiteColorData); // 位图信息头 BITMAPINFOHEADER ldBmpInfoHeader = {0}; ldBmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER); ldBmpInfoHeader.biWidth = lulPixelWidth; ldBmpInfoHeader.biHeight = lulPixelHeight; ldBmpInfoHeader.biPlanes = 1; ldBmpInfoHeader.biBitCount = 8; ldBmpInfoHeader.biCompression = BI_RGB; ldBmpInfoHeader.biSizeImage = 0; ldBmpInfoHeader.biXPelsPerMeter = 0; ldBmpInfoHeader.biYPelsPerMeter = 0; ldBmpInfoHeader.biClrUsed = 0; ldBmpInfoHeader.biClrImportant = 0; // 位图文件头 BITMAPFILEHEADER ldBmpFileHeader = {0}; ldBmpFileHeader.bfType = 0x4D42; // "BM" ldBmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD); // 数据部分偏移 LONG llCbPerRow = ldBmpInfoHeader.biWidth + (ldBmpInfoHeader.biWidth % 4 > 0 ? 4 - ldBmpInfoHeader.biWidth % 4 : 0); // 每行实际占据的字节数(四字节对齐) LONG llCbData = llCbPerRow * ldBmpInfoHeader.biHeight; // 数据总共占据的字节数 ldBmpFileHeader.bfSize = ldBmpFileHeader.bfOffBits + llCbData; // 颜色表 RGBQUAD ldColorTable[256] = {{0,0,0,0},{255,255,255,0}}; for(int i = 0; i < 256; ++i) { ldColorTable[i].rgbBlue = i; ldColorTable[i].rgbGreen = i; ldColorTable[i].rgbRed = i; ldColorTable[i].rgbReserved = 0; } // 构建位图 HANDLE lhFile = CreateFile(nswBmpFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(NULL == lhFile) { break; } DWORD ldwCbWritten = 0; WriteFile(lhFile, (LPVOID)&ldBmpFileHeader, sizeof(BITMAPFILEHEADER), &ldwCbWritten, NULL); WriteFile(lhFile, (LPVOID)&ldBmpInfoHeader, ldBmpInfoHeader.biSize, &ldwCbWritten, NULL); WriteFile(lhFile, (LPVOID)&ldColorTable, 256 * sizeof(RGBQUAD), &ldwCbWritten, NULL); // 每行为了对齐所需要填充的数据 ULONG lulCbForFill = llCbPerRow -ldBmpInfoHeader.biWidth; PBYTE lpDataForFill = NULL; if(lulCbForFill > 0) { lpDataForFill = new BYTE[lulCbForFill]; RtlZeroMemory(lpDataForFill, lulCbForFill); } // 每行实际数据缓冲 for(int i = 0; i < ldBmpInfoHeader.biHeight / liZoomInY; ++i) { for(int y = 0; y < liZoomInY; ++y) { WriteFile(lhFile, (LPVOID)&lpPixelData[i * lulBmpWidth], lulPixelWidth, &ldwCbWritten, NULL); if(lulCbForFill > 0) WriteFile(lhFile, (LPVOID)lpDataForFill, lulCbForFill, &ldwCbWritten, NULL); } } SAFE_DELETE(lpPixelData); SAFE_DELETE(lpDataForFill); CloseHandle(lhFile); lbRet = true; } while (false); if(NULL != ldPdf417Info.text) delete ldPdf417Info.text; pdf417free(&ldPdf417Info); return lbRet;} // 颜色表 RGBQUAD ldColorTable[256] = {{0,0,0,0},{255,255,255,0}}; for(int i = 0; i < 256; ++i) { ldColorTable[i].rgbBlue = i; ldColorTable[i].rgbGreen = i; ldColorTable[i].rgbRed = i; ldColorTable[i].rgbReserved = 0; }// 256 grey color而 + 2 * sizeof(RGBQUAD) 只有 2个 ? 69行ldBmpInfoHeader.biSizeImage = 0;改为ldBmpInfoHeader.biSizeImage = ((lulPixelWidth + 3) & ~3) * lulPixelHeight;试试看 CDialog的派生,继承问题?? 如何在一个类中调用另一个类的函数 已经得到WMV文件DATA以及后面的数据,如何生成一个符合DATA部分的WMV头 求封装http协议的类 在IE工具条上添加一个类似滚动新闻那样的滚动条的控件 问一下打印问题 如何设置ADO数据库的AbsolutePage UpdateWindow到底器什么作用? 一个17岁的小男孩!我需要你们的帮助!! OA 如何屏匿手按键盘的消息,只允许发自扫描器的消息? 刻录
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;红的不对
ldBmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD); // 数据部分偏移这是我源代码部分。 而且假如这里不对的话,画图程序怎么能正常显示出数据呢
bool Make2DBarCodeBmp(const wchar_t* nswCodeContent, const wchar_t* nswBmpFile, UINT nuiZoomIn)
{
if(NULL == nswCodeContent || NULL == nswBmpFile)
return false; bool lbRet = false;
pdf417param ldPdf417Info = {0};
do
{
// 构造数据
pdf417init(&ldPdf417Info);
ldPdf417Info.text = UnicodeToAnsi(nswCodeContent);
ldPdf417Info.options = PDF417_INVERT_BITMAP;
paintCode(&ldPdf417Info); if(PDF417_ERROR_SUCCESS != ldPdf417Info.error)
{
pdf417free(&ldPdf417Info);
break;
} // -------------------------------------------------------------------------------------------------------------------------------
// 8位位图,一个像素占据一位,方便缩放处理
// ------------------------------------------------------------------------------------------------------------------------------- // 放大倍数
int liZoomInX = nuiZoomIn;
int liZoomInY = nuiZoomIn; // 将ldPdf417Info.lenBits中以位为单位的总字节数为ldPdf417Info.outBits的像素值转换成以字节为单位的像素值
ULONG lulPixelWidth = ldPdf417Info.bitColumns * liZoomInX;
ULONG lulPixelHeight = ldPdf417Info.codeRows * liZoomInY;
ULONG lulBmpWidth = ldPdf417Info.lenBits * 8 / ldPdf417Info.codeRows * liZoomInX; // 因为BMP图存储时数据部分必须四字节对齐,所以Bmp图宽度和像素宽度不一定相同,拷贝数据的时候要以BMP图宽度为准 ULONG lulCbRealDataWithoutRepeatRows = ldPdf417Info.lenBits * 8 * liZoomInX; // 除去了重复行的有效数据字节数
PBYTE lpPixelData = new BYTE[lulCbRealDataWithoutRepeatRows]; // 扩充X倍
RtlZeroMemory(lpPixelData, lulCbRealDataWithoutRepeatRows); // 扩充后的白色像素点数据
ULONG lulRateX = 1 * liZoomInX; // 放大后水平方向上之前每字节对应现在多少个字节
PBYTE lpWhiteColorData = new BYTE[lulRateX];
memset(lpWhiteColorData, 0xFF, lulRateX); BYTE lbBitMask = 0x80;
PBYTE lpCrtPos = lpPixelData;
for(int i = 0; i < ldPdf417Info.lenBits * 8; ++i)
{
if(ldPdf417Info.outBits[i / 8] & lbBitMask)
{
RtlCopyMemory(lpCrtPos, lpWhiteColorData, lulRateX);
} lpCrtPos += lulRateX; lbBitMask = lbBitMask >> 1;
if(lbBitMask == 0)
lbBitMask = 0x80;
}
SAFE_DELETE(lpWhiteColorData); // 位图信息头
BITMAPINFOHEADER ldBmpInfoHeader = {0};
ldBmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
ldBmpInfoHeader.biWidth = lulPixelWidth;
ldBmpInfoHeader.biHeight = lulPixelHeight;
ldBmpInfoHeader.biPlanes = 1;
ldBmpInfoHeader.biBitCount = 8;
ldBmpInfoHeader.biCompression = BI_RGB;
ldBmpInfoHeader.biSizeImage = 0;
ldBmpInfoHeader.biXPelsPerMeter = 0;
ldBmpInfoHeader.biYPelsPerMeter = 0;
ldBmpInfoHeader.biClrUsed = 0;
ldBmpInfoHeader.biClrImportant = 0; // 位图文件头
BITMAPFILEHEADER ldBmpFileHeader = {0};
ldBmpFileHeader.bfType = 0x4D42; // "BM"
ldBmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD); // 数据部分偏移
LONG llCbPerRow = ldBmpInfoHeader.biWidth + (ldBmpInfoHeader.biWidth % 4 > 0 ? 4 - ldBmpInfoHeader.biWidth % 4 : 0); // 每行实际占据的字节数(四字节对齐)
LONG llCbData = llCbPerRow * ldBmpInfoHeader.biHeight; // 数据总共占据的字节数
ldBmpFileHeader.bfSize = ldBmpFileHeader.bfOffBits + llCbData; // 颜色表
RGBQUAD ldColorTable[256] = {{0,0,0,0},{255,255,255,0}};
for(int i = 0; i < 256; ++i)
{
ldColorTable[i].rgbBlue = i;
ldColorTable[i].rgbGreen = i;
ldColorTable[i].rgbRed = i;
ldColorTable[i].rgbReserved = 0;
} // 构建位图
HANDLE lhFile = CreateFile(nswBmpFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(NULL == lhFile)
{
break;
} DWORD ldwCbWritten = 0;
WriteFile(lhFile, (LPVOID)&ldBmpFileHeader, sizeof(BITMAPFILEHEADER), &ldwCbWritten, NULL);
WriteFile(lhFile, (LPVOID)&ldBmpInfoHeader, ldBmpInfoHeader.biSize, &ldwCbWritten, NULL);
WriteFile(lhFile, (LPVOID)&ldColorTable, 256 * sizeof(RGBQUAD), &ldwCbWritten, NULL); // 每行为了对齐所需要填充的数据
ULONG lulCbForFill = llCbPerRow -ldBmpInfoHeader.biWidth;
PBYTE lpDataForFill = NULL;
if(lulCbForFill > 0)
{
lpDataForFill = new BYTE[lulCbForFill];
RtlZeroMemory(lpDataForFill, lulCbForFill);
} // 每行实际数据缓冲
for(int i = 0; i < ldBmpInfoHeader.biHeight / liZoomInY; ++i)
{
for(int y = 0; y < liZoomInY; ++y)
{
WriteFile(lhFile, (LPVOID)&lpPixelData[i * lulBmpWidth], lulPixelWidth, &ldwCbWritten, NULL);
if(lulCbForFill > 0)
WriteFile(lhFile, (LPVOID)lpDataForFill, lulCbForFill, &ldwCbWritten, NULL);
}
}
SAFE_DELETE(lpPixelData);
SAFE_DELETE(lpDataForFill); CloseHandle(lhFile); lbRet = true;
} while (false);
if(NULL != ldPdf417Info.text)
delete ldPdf417Info.text;
pdf417free(&ldPdf417Info);
return lbRet;
}
RGBQUAD ldColorTable[256] = {{0,0,0,0},{255,255,255,0}};
for(int i = 0; i < 256; ++i)
{
ldColorTable[i].rgbBlue = i;
ldColorTable[i].rgbGreen = i;
ldColorTable[i].rgbRed = i;
ldColorTable[i].rgbReserved = 0;
}
// 256 grey color
而 + 2 * sizeof(RGBQUAD)
只有 2个 ?
ldBmpInfoHeader.biSizeImage = 0;
改为
ldBmpInfoHeader.biSizeImage = ((lulPixelWidth + 3) & ~3) * lulPixelHeight;
试试看