Search code examples
node.jsencodingpngfszlib

Nodejs - Writing and encoding a PNG file with only FS and ZLIB modules


I'm trying to generate a .png image from a hexadecimal color string (#RRGGBB), without using modules like pngjs or jimp.

The hex string looks like this:

let colors = "ff000000ff000000ffff00ff00ffffffff00";

According to this article, all png files must start with the signature b'\x89PNG\r\n\x1a\n' and have 3 "chunks" (IHDR, IDAT and IEND), each with the following structure:

enter image description here (Data Length, Chunk Type, Chunk Data and CRC)

And according to png specs, it is compressed with zlib's deflate, so I came up with this code:

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;});
});

For better readability, the split data looks like this:

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

What I expected to get as a result was the image below (in its 3x2 size), but all I have is a seemingly invalid png file that my image viewer doesn't support.

image with 6 pixels of different colors

Is it really possible to write a valid png file this way? If so, how?


Solution

  • Those pixels in a PNG (you will need to dramatically embiggen in order to see the six pixels):

    2x3 colors

    Hex dump:

    89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52
    00 00 00 03 00 00 00 02 08 02 00 00 00 12 16 f1
    4d 00 00 00 17 49 44 41 54 08 99 63 f8 cf c0 c0
    f0 9f 81 81 e1 3f 0b 94 fe cf 08 00 39 04 06 00
    83 e9 a9 e3 00 00 00 00 49 45 4e 44 ae 42 60 82