【发布时间】:2022-01-25 23:07:40
【问题描述】:
我正在尝试从十六进制颜色字符串 (#RRGGBB) 生成 .png 图像,而不使用 pngjs 或 jimp 等模块。
十六进制字符串如下所示:
let colors = "ff000000ff000000ffff00ff00ffffffff00";
根据this article,所有png文件必须以签名b'\x89PNG\r\n\x1a\n'开头,并有3个“块”(IHDR、IDAT和IEND),每个块的结构如下:
并且根据png specs,它是用zlib's deflate压缩的,所以我想出了这个代码:
const fs = require("fs");
const zlib = require("zlib");
let colors = "ff000000ff000000ffff00ff00ffffffff00";
let data = `b'\x89PNG\r\n\x1a\n'0d00IHDR030002008200000002400IDAT${colors}0000IEND`;
zlib.deflateRaw(data, (err, buffer) => {
fs.writeFile("output.png", buffer, (err)=>{if (err) throw err;});
});
为了更好的可读性,拆分后的数据如下所示:
b'\x89PNG\r\n\x1a\n' // signature
0d00 // chunk data length (13)
IHDR // chunk type
/* chunk data */
0300 // image width (3)
0200 // image height (2)
8 // bit depth (8)
2 // color type (2)
0 // compression method (0)
0 // filter method (0)
0 // interlace method (0)
0000 // CRC (?)
2400 // chunk data length (36)
IDAT // chunk type
ff000000ff000000ffff00ff00ffffffff00 // chunk data (#RRGGBB)
0000 // CRC (?)
IEND
我期望得到的是下面的图像(3x2 大小),但我所拥有的只是一个看似无效的 png 文件,我的图像查看器不支持。
真的可以这样写一个有效的png文件吗?如果有,怎么做?
【问题讨论】:
-
错得太离谱了,我什至不知道从哪里开始。我建议您从一个有效的小型 PNG 文件开始,并弄清楚如何逐字节解释它。而不是试图制造一个。一旦你看到它是如何组合在一起的,然后试着自己做一个。
-
@MarkAdler 好吧,我已经提供了我为得出这个结论而采取的所有步骤,如果你能指出我所犯的最大错误,那将会很有帮助。
-
最大的错误是没有花足够的时间使用 PNG 规范,也没有花时间挑选有效的 PNG 文件(您链接的文章是一个好的开始),然后才开始尝试制作自己的PNG文件进行随机猜测。您将无法通过尝试纠正错误来逐步接近有效的 PNG 文件,因为从这里到那里没有路径。删除您所做的并重新开始。
-
好的,但是你认为我正在尝试做的是一种有效的方法吗?我的意思是,只是将值转换为十六进制,将它们连接成一个字符串,对其进行编码,然后将其写入扩展名为 .png 的文件中有意义吗?我对那篇文章(除了关于解码,而不是编码)和我迄今为止读过的其他一些文章的问题是,他们都没有只使用 fs 和 zlib 模块来处理 nodejs 的这种特定情况。
-
不,这根本没有任何意义。格式为二进制。没有任何内容以十六进制编码。
标签: node.js encoding png fs zlib