[ANN] File-to-image

205 views
Skip to first unread message

Martin Eden

unread,
Jan 21, 2026, 3:54:11 PMJan 21
to lu...@googlegroups.com
Hello guys,

This evening I wrote simple tool to represent bytes as grayscale pixels.

If someone wants to experiment with it, code is here:

  https://github.com/martin-eden/Lua-BinToImg

It uses spiral filling (and basic turtle class). For image serialization
text PNM format is used. Conversion to PNG is done via third-party tool.

As usually it's self-sufficient repo and all code is written by me.


Did anyone experiment with space-filling curves?

Like Peano's or Hilbert's? I wrote simple spiral on square grid and
quite happy with results. Of course I tried raster (left-to-right,
newline) filling and it's boring.


-- Martin


Denis Dos Santos Silva

unread,
Jan 22, 2026, 9:51:50 AMJan 22
to lua-l
awesome!!!

Lars Müller

unread,
Jan 24, 2026, 12:40:38 PMJan 24
to lu...@googlegroups.com
Fun fact: PNG is actually a very simple format, especially if you just want to write an ARGB8 file.

I have some related code around: https://github.com/appgurueu/modlib/blob/59ed71df15e4e01e0bb096e7b1d709ea9fdb25cb/minetest/png.lua

This uses some Luanti (formerly Minetest) APIs that wrap zlib to do the (de)compression.
It's pretty short, about ~100 loc for the encoder. There's also a pretty much full-fledged decoder there.
That is a couple more hundred lines, but still not that large.

So what I'm saying is, if it tickles your fancy, directly writing PNGs from Lua is an option.

Or just bindings to libpng. 🙃

- Lars

p.s. alternatively, there's also the "quite okay image format" (QOI, https://qoiformat.org/) that seems to live up to its name and is even simpler than PNG.


--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/lua-l/84351670-be18-4621-bf03-314c36032fe5n%40googlegroups.com.

Martin Eden

unread,
Jan 25, 2026, 10:21:47 AMJan 25
to lu...@googlegroups.com
On 2026-01-24 19:40, 'Lars Müller' via lua-l wrote:
> Fun fact: PNG is actually a very simple format, especially if you just
> want to write an ARGB8 file.
>
> I have some related code around:
> <https://github.com/appgurueu/modlib/blob/59ed71df15e4e01e0bb096e7b1d709ea9fdb25cb/minetest/png.lua>
>
> This uses some Luanti (formerly Minetest) APIs that wrap zlib to do
> the (de)compression.
> It's pretty short, about ~100 loc for the encoder. There's also a
> pretty much full-fledged decoder there.
> That is a couple more hundred lines, but still not that large.
>
> So what I'm saying is, if it tickles your fancy, directly writing PNGs
> from Lua is an option.
>
> Or just bindings to libpng. 🙃
>
> - Lars
>
> p.s. alternatively, there's also the "quite okay image format" (QOI,
> <https://qoiformat.org/>) that seems to live up to its name and is
> even simpler than PNG.
>
Hello Lars,

Thanks for related sources to PNG and QOI. Yeah I know that PNG is not
complex for simple cases. But even in your use case it requires deflate
codec.

I've discovered there is text format that is almost as simple as
possible. Just ASCII tokens:

  P2
  3 2 255
  128 000 64
  092 000 32

So codec for it can be written on-the-fly without reading documentation.
It is supported by stock viewer on my Linux Mint so so far it is best
fit for my mathematical experiments. (Which is basically just
generating and visualizing integer matrices.)

Of course there is no compression, so generated files are not suitable
for storing in collections.

But it amazes me how fast and simple I can do things in Lua
(in comparison with say C or Pascal). For example there to set pixel
I typically have to create record like (x: int, y: int) or
take coordinates as explicit "x" and "y" arguments. In Lua I'm just
passing { 100, 50 } without even bothering to name data and not
thinking about strict types compatibility.

-- Martin

Olive Simmons

unread,
Jan 29, 2026, 7:21:36 PMJan 29
to lu...@googlegroups.com
> >
https://github.com/appgurueu/modlib/blob/59ed71df15e4e01e0bb096e7b1d709ea9fdb25cb/minetest/png.lua
> > So what I'm saying is, if it tickles your fancy, directly writing
PNGs from Lua is an option.
> >
> > This uses some Luanti (formerly Minetest) APIs that wrap zlib to
do the (de)compression.
> > It's pretty short, about ~100 loc for the encoder. There's also a
pretty much full-fledged decoder there.
>
> Yeah I know that PNG is not complex for simple cases. But even in
your use case it requires deflate codec.

Writing usable deflate from within Lua is pretty easy, compression can
be skipped and you can just write uncompressed chunks. The RFC is
pretty confusing trying to work on a bit-stream but still have
endianness, here's an extract from a script of mine you can maybe adapt:

local spack, char, concat = string.pack, string.char, table.concat
local function writedeflatechunk(file, s, final)
file:write(spack("<BI2I2", final and 0x01 or 0x00, #s, (~#s)&0xffff)
.. s)
end
-- works on 0-based arrays
local function writedeflate(file, data)
for i = 0, #data, 1024-5 do
if data[i+1023-5] then
local cmap = {} for j=0,1023-5 do cmap[j+1] = char(data[i+j])
end
writedefchunk(file, concat(cdata))
else
local cmap = {} for j=0,#map-i do cmap[j+1] = char(data[i+j])
end
writedefchunk(file, concat(cdata), true)
end
end
end

(ps. if there's a better way to turn a 0-based array into a byte string
I'd love to know, surprisingly this isn't a huge performance issue)

> I've discovered there is text format that is almost as simple as
possible.

PNM/PBM/PGM files!
It's a super handy format for chucking out graphs and image work, if
you install netpbm from your package manager you'll get a whole list of
{pbm,pgm,pam}to{png,gif,tiff,svg,tga,...} and vice-versa commands.
Unfortunately it doesn't actually have wide support in most image
progams, iirc gimp works with it, and about half of Linux image viewers
seem to. A bit silly given it's so simple.



Martin Eden

unread,
Jan 30, 2026, 2:25:10 PMJan 30
to lu...@googlegroups.com

On 2026-01-30 01:45, Olive Simmons wrote:
> Writing usable deflate from within Lua is pretty easy, compression can
> be skipped and you can just write uncompressed chunks. The RFC is
> pretty confusing trying to work on a bit-stream but still have
> endianness, here's an extract from a script of mine you can maybe adapt:
> [...]
>
Hello Olive,

I have no doubts I can do output in PNG format.

But question is what program should do?

That one-day project was about "how binary file looks if it's data
are displayed as spiral?". So program just generates mapping
from 1-d byte position to 2-d pixel position. I can't see
result so stored that pixels as file in known text format.

That P?M format is not widely supported, so I wrote script to
call available CLI tool to convert it to PNG. PNG is mainstream now,
even Internet browser can display it.

What further happens with that PNG is not my code's business.
Code's business is provide tweakable code for 1-d -> 2-d mapping.

-- Martin


Reply all
Reply to author
Forward
0 new messages