写入BMP数据时出现垃圾数据

4
我正在研究和绘制自己的PDF417(二维条形码)DLL。无论如何,文件的实际绘制是完美的,并且在32位的正确边界内(作为单色结果)。在编写数据时,以下是从C ++ Visual Studio内存转储复制的指向bmp缓冲区的指针的内存转储。每行在下一行之前正确分配为36个宽度。
对于帖子中的换行表示抱歉,但我的输出意图是与内存转储相同的36字节宽度,以便您更好地看到扭曲情况。
当前绘制的宽度为273像素,高度为12像素,单色...
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00 00
00 ab 85 7e d0 29 e8 14 f4 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0a 8e 02 eb 00 00
00 ab 85 7e d0 29 e8 14 f4 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0a 8e 02 eb 00 00
00 ab 85 7e d0 29 e8 14 f4 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0a 8e 02 eb 00 00
00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c db ce 6d 5f be 02 eb 00 00
00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c db ce 6d 5f be 02 eb 00 00
00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c db ce 6d 5f be 02 eb 00 00

以下是关于从上述内存转储中立即按原样写出文件的代码:
FILE *stream; 
if( fopen_s( &stream, cSaveToFile, "w+" ) == 0 ) 
{ 
   fwrite( &bmfh, 1, (UINT)sizeof(BITMAPFILEHEADER), stream ); 
   fwrite( &bmi, 1, (UINT)sizeof(BITMAPINFO), stream ); 
   fwrite( &RGBWhite, 1, (UINT)sizeof(RGBQUAD), stream );
   fwrite( ppvBits, 1, (UINT)bmi.bmiHeader.biSizeImage, stream ); 
   fclose( stream ); 
}

以下是实际写入文件的内容。
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab a8 61 d7 18 ed 18 f7 a3 89 1c dd 70 86 f5 f7 1a 20 91 3b c9 27 e7 67 12 1c 68 ae 3c b7 3e 02 eb 00 00
00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0d 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb 00
00 00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0d 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02 eb
00 00 00 ab 81 4b ca 07 6b 9c 11 40 9a e6 0c 76 0d 0a fc a3 33 70 bb 30 55 87 e9 c4 10 58 d9 ea 0d 48 3e 02
eb 00 00 00 ab 85 7e d0 29 e8 14 f4 0d 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c 0d 0a
8e 02 eb 00 00 00 ab 85 7e d0 29 e8 14 f4 0d 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79 bc 5c
0d 0a 8e 02 eb 00 00 00 ab 85 7e d0 29 e8 14 f4 0d 0a 7a 05 3c 37 ba 86 87 04 db b6 09 dc a0 62 fc d1 31 79
bc 5c 0d 0a 8e 02 eb 00 00 00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c
db ce 6d 5f be 02 eb 00 00 00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c
db ce 6d 5f be 02 eb 00 00 00 ab 85 43 c5 30 e2 26 70 4a 1a f3 e4 4d ce 2a 3f 79 cd bc e6 de 73 6f 39 b7 9c
db ce 6d 5f be 02 eb 00 00

注意在第4行读取文件后,结果中的“0d”开始出现扭曲,大约在第15个字节处......然后,还有几个字节错开,总共偏移了9个字节的长度......

显然,绘图部分工作正常,因为所有内容在内存中仍然正确对齐了12行。

3个回答

10

你是否应该以复合模式即可写、二进制方式打开文件,例如使用wb+

注意到扭曲的起点是“0d”

这是回车符(CR)的ASCII码,在一些操作系统上与换行符(其中换行符实际上是CR/LF序列)一起添加。一旦你开始以二进制模式写入输出,这个问题应该就会消失。

你的代码其他看起来很整洁。干杯!


5

因为您在文本模式下写入文件,所以您的 0x0A (\n) 会被转换为 DOS 格式的 0x0D0A (\r\n)。请切换到二进制模式。


0

我之前在Java中做过类似的事情(将BMP数据打印到热敏收据打印机上)。这里有几件事情我想和你分享:

  1. BMP图像数据!=来自Microsoft的图像格式。 MS位图在任何图像数据之前有约54个字节的头信息。(我在意识到差异之前花了一两天时间)

  2. BMP图像数据从左到右,从上到下读取,最重要的位在左侧。

  3. 确保条形码图像的位深度为1。这意味着1位= 1像素。十六进制“ab”在二进制中为10101011,这8个像素将相应地填充。

  4. 如果您有一个36字节宽的条形码,则条形码分辨率为288 x 12,而不是273 x 12。(36 * 8 = 288)。

  5. 图像数据的大小应为432字节(12行36字节)。

  6. 我不知道这是什么意思:

    无论如何,文件的实际绘制是完美的,并且在32位的正确边界内(作为单色结果)。

单色意味着它只有一种颜色。像素(想象一下位)要么被填充,要么没有填充。

希望这能有所帮助


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接