To encode the binary as a PNG image, the dimensions of the image must first be decided on. For this, I decided to set the image width to the smallest power of two that allowed the image to have a landscape aspect ratio, although this decision was somewhat arbitrary. Each pixel in the grayscale image corresponds to one byte in the WebAssembly binary, starting in the top-left corner of the image and wrapping line-by-line. Any remaining pixels in the last row of the image were set to zero, but this presented a problem, since zero-padding a WebAssembly binary is not allowed. Thus, the first four pixels of the image are used to store the size of the WebAssembly binary as an unsigned 32-bit little-endian integer, which can then be used by the decoder to truncate the image data to the correct length. The resulting PNG image can then be optimized using tools such as OxiPNG to reduce its file size further, after which the PNG image is Base64-encoded as a data URI.
Image() constructor is used to create an
<image> element from the Base64-encoded string. Then, the
<image> is drawn to a
<canvas> element, and the
getImageData() method is used to extract the image data as an array. The array is then filtered to keep only every fourth pixel, to convert the RGBA data to grayscale.2 Next, the first four bytes containing the WebAssembly binary length are decoded, removed from the array, and used to truncate the array to just the WebAssembly binary data. Finally, these data are used to instantiate the WebAssembly code. The decoding routine is <0.3 kB after gzip compression.
gzip -9, and ~218 kB when compressed with
brotli -9. As a Base64-encoded string, it is ~880 kB, which is reduced to ~358 kB when compressed with
gzip -9 or ~316 kB when compressed with
brotli -9. When converted to a PNG image using the technique described in this blog post and optimized using OxiPNG, the resulting image is ~242 kB. When converted to a Base64-encoded data URI, it is ~322 kB, which is reduced to ~244 kB when compressed with
gzip -9 or ~242 kB when compressed with