This is my next Zig project, and it’s certainly larger than my last couple. It’s txt2img, a simple CLI tool that lets you generate a customizable image with text on it from the command line. The reason I wrote this is that I often need just a simple PNG with text for a logo, artwork, etc., as a blind developer, and I really don’t want to shell out to an AI for that when some basic code can do me just fine.
This was a great opertunity to learn about Zig’s C interop, it works wonderfully! Although, I would absolutely welcome suggestions on how to ditch the tiny bit of C I had to write to make the STB libraries I used fully link into Zig.
Usage: txt2img "text to draw" [<options>]
Options:
-o, --output name of the file to write to. Defaults to output.png
-s, --size <width>x<height> specifies the size, in pixels, of the generated image. Defaults to 512x512
-bg <color> specifies the background color of the image, see below for details on valid colors. Defaults to white
-fg <color> specifies the foreground color of the image, see below for details on valid colors. Defaults to black
-p, --pos <X,Y> specifies the starting position of the text in the image. Defaults to 16,32
Notes:
Colors accept names (white, black, red, etc.), #RRGGBB, or #RRGGBBAA
I certainly welcome any feedback, but especially around the C linkage and how the images look, I’m fully blind and the only validation I’ve gotten that this works is OCR and having an AI describe a few generated pictures.
Linking the implementation part of c single header libraries via a c-source file that defines the #define STB_IMAGE_WRITE_IMPLEMENTATION is the correct approach, that way the c-Include only runs on the header-part and not on the implementation part, doing this is good, because c-Include doesn’t translate every c code without errors. When it only translates the header-/declaration-part it is more likely to work correctly.
The text is readable, but relatively small, so it might be useful to have an option to change the size of the font.
Because it seems to be a pixel perfect font, maybe you could increase font size in integer increments?
When I passed a very long line of text, it silently got cut off once it no longer was within the 512x512 image region, similarly when I send it very many lines it would go past the bottom of the image.
I think it may help you catch errors, if you make sure that this results in an error message.
Yup, this all makes perfect sense. Thanks a ton! They’re all things I didn’t consider, but they make perfect sense and I’ll spend some time hacking on it
main.zig:145:43: 0x7ff7704b0921 in drawText (txt2img_zcu.obj) @memcpy(text_buf[0..cli.text.len], cli.text);
Error for me when using on windows with zig 15.2
Oooh, this definitely looks interesting! I won’t have a ton of time to explore it until this weekend, but thanks a ton for pointing me at it, this looks terrific! Wrapping STB was great for learning how @cImport works, but having it all be Zig would be great.
Wow, you’re awesome, thanks loads! I’ll review this right before going to bed. Let’s see how Codeberg’s PR reviewing screen works with screen readers, if it’s better than the mess GitHub cranked out.