【问题标题】:How to generate 2 pixel BMP image with Awk?如何使用 Awk 生成 2 像素 BMP 图像?
【发布时间】:2015-03-03 14:53:59
【问题描述】:

抱歉这个愚蠢的问题,但我正在尝试使用 Awk 创建(生成)一个简单的 BMP 图像 2x1、24 位像素格式 RGB24 位图。

格式为“BitmapFileHeader (2+4+4+4=14 bytes) + DIBHeader (4+4+4+2+2+4+4+4+4+4+4=40 bytes) = 54byte” ,然后是像素数组(位图数据)的开始。这是我的简单脚本:

BEGIN {
ORS="";
filebmp="Image.bmp"
# BMP Header: 2+4+4+4=14 bytes
printf("%c%c",66,77)>filebmp;
printf("%c%c%c%c",62,0,0,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;
printf("%c%c%c%c",54,0,0,0)>filebpm;

# DIB Header: 4+4+4+2+2+4+4+4+4+4+4=40 bytes
printf("%c%c%c%c",40,0,0,0)>filebmp;
printf("%c%c%c%c",2,0,0,0)>filebmp;
printf("%c%c%c%c",1,0,0,0)>filebmp;
printf("%c%c",1,0)>filebmp;
printf("%c%c",24,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;
printf("%c%c%c%c",8,0,0,0)>filebmp;
printf("%c%c%c%c",19,11,0,0)>filebmp;
printf("%c%c%c%c",19,11,0,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;
printf("%c%c%c%c",0,0,0,0)>filebmp;

# start of pixel array (bitmap data)
# Blu pixel
printf ("%c%c%c",127,0,0)>filebmp;
# Green pixel
printf ("%c%c%c",0,127,0)>filebmp;
# Padding
printf ("%c%c",0,0)>filebmp;
}

它的工作原理(下图):它生成一个 2x1 和 62 字节大小的 BMP 图像。

http://i60.tinypic.com/mlihyt.jpg

但是,现在,如果在位图数据中我将 127 值替换为 128(例如蓝色像素),相同的脚本 Awk 会生成一个 2x1 但 63 字节大小和“其他颜色”的 BMP 图像(见下图)!

http://i62.tinypic.com/2ltkjlg.png

我想知道我哪里出错了......

...有什么想法吗?

谢谢,再见

【问题讨论】:

  • 我在您发布时运行了您的脚本,然后再次使用 128 而不是 127,但无法重现该问题。两个结果都是 62 个字符,二进制差异只显示了预期的 0x80,而 0x7F 是。我确实注意到您发布的内容中有一个错字:filebpm 而不是 filebmp 用于其中一个文件名。您确定您发布的内容正是您正在运行的内容吗? (并不是说这本身就可以解释你所看到的。)
  • 另外,man ascii 会告诉您127 是表中的最后一个%c 值。因此,不确定是否为 %c 定义了 128。使用 awk 的有趣问题。祝你好运!
  • 哦,我在您的输出十六进制字节c2 80 中看到,这恰好是 0x80(十进制 128)控制字符的 UTF8 编码。我认为我们正在取得进展......
  • 您到底为什么要使用awk

标签: image awk bitmap


【解决方案1】:

我能够用 gawk 重现该问题。似乎 gawk 根据您的 LANG 环境变量选择输出编码。 (这里我将两个 127 实例都更改为 128。)

$ LANG=en_US.LATIN1 gawk -f bit.awk
$ wc -c Image.bmp
  62 Image.bmp

00000000: 424d 3e00 0000 0000 0000 3600 0000 2800  BM>.......6...(.
00000010: 0000 0200 0000 0100 0000 0100 1800 0000  ................
00000020: 0000 0800 0000 130b 0000 130b 0000 0000  ................
00000030: 0000 0000 0000 8000 0000 8000 0000       ..............

$ LANG=en_US.UTF-8 gawk -f bit.awk
$ wc -c Image.bmp
  64 Image.bmp

00000000: 424d 3e00 0000 0000 0000 3600 0000 2800  BM>.......6...(.
00000010: 0000 0200 0000 0100 0000 0100 1800 0000  ................
00000020: 0000 0800 0000 130b 0000 130b 0000 0000  ................
00000030: 0000 0000 0000 c280 0000 00c2 8000 0000  ................

在单字节编码下运行 gawk 应该没问题。

【讨论】:

  • LANG 环境变量设置为 LANG=it_IT.UTF8。我已将 LANG 本地化从 it_IT.UTF8 更改为 it_IT@euro e 现在它可以工作了。我真的很感谢大家和我一起解决这个“小问题”。
  • 很好的分析。使用LC_ALL=C gawk -f bit.awk 可能是最可靠的方法。值得注意的是,BSD awkmawk 都没有表现出这种行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
  • 2022-01-02
  • 2021-01-25
相关资源
最近更新 更多