# New image processing library: Zignal

**URL:** <https://ziggit.dev/t/new-image-processing-library-zignal/4011>\
**Category:** Showcase\
**Tags:** llm\
**Created:** [April 19, 2024, 6:46am UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011 "2024-04-19T06:46:56Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![adria](https://ziggit.dev/user_avatar/ziggit.dev/adria/32/605_2.png) [@adria](https://ziggit.dev/u/adria)\
**Post date:** [April 15, 2026, 8:47pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/21 "2026-04-15T20:47:01Z")

</div>

Hi everyone!

Zignal 0.10.0 is out. compilable with Zig 0.16.0.

There are the usual performance improvements and bug fixes, but the main highlight is a simple CLI tool to perform various image operations via the terminal.

You can get an idea of what it can do with:

```console
Usage: zignal [options] <command> [command-options]

Global Options:
  --log-level <level> Set the logging level (err, warn, info, debug)

Commands:
  blur Apply various blur effects to images.
  diff Compute the visual difference between two images.
  display Display an image in the terminal using supported graphics protocols.
  edges Perform edge detection on an image using Sobel, Canny, or Shen-Castan algorithms.
  fdm Apply Feature Distribution Matching (style transfer) from target to source image.
  info Display detailed information about one or more image files.
  metrics Compute quality metrics (PSNR, SSIM, Mean Error) between a reference and target images.
  resize Resize an image using various interpolation methods.
  tile Combine multiple images into a single tiled image.
  version Display version information.
  help Display this help message

Run 'zignal help <command>' for more information on a specific command.

```

For example:

```console
zignal help display

Usage: zignal display <image> [options]

Display an image in the terminal using supported graphics protocols.

Options:
  --width <N> Target width in pixels
  --height <N> Target height in pixels
  --protocol <p> Force protocol: kitty, sixel, sgr, braille, auto

```

Full release notes here:

> **[Release zignal 0.10.0 · arrufat/zignal](https://github.com/arrufat/zignal/releases/tag/0.10.0)**
>
> Zignal 0.10.0
> This release brings full compatibility with Zig 0.16.0, a robust new Command Line Interface, new computer vision algorithms, and significant performance optimizations across the board...

---

<div class="post-metadata">

**Author:** ![mnemnion](https://ziggit.dev/user_avatar/ziggit.dev/mnemnion/32/2478_2.png) [@mnemnion](https://ziggit.dev/u/mnemnion)\
**Post date:** [April 15, 2026, 10:55pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/22 "2026-04-15T22:55:26Z")

</div>

> [@adria](#):
>
> Here, all lines can fail for various reasons, and the error will only be reported by the `.eval()` call.  
> It’s not perfect, but it’s the best I could think of. Open to suggestions.

I think the ‘railroad’ like you’re doing here is as good as it gets for chaining in Zig. And it’s pretty good!

Maybe not worth changing, but I find `eval` confusing as the name of the finalizer. It makes me think that all the calls before are setting up an operation, and only the final one does it. But it [looks like](https://github.com/arrufat/zignal/blob/3cf5a61729bbfd7ef38b6b62c976c9cec030163e/src/matrix/Matrix.zig#L940) that isn’t how it works.

I would use `ok()` here for that reason. That I would read right away as “oh, right, the `try`, railroad pattern”. If you’re past the point where tweaking the API for surface reasons like that feels worth doing, that’s understandable.

It’s been neat seeing this project grow, good work.

---

<div class="post-metadata">

**Author:** ![adria](https://ziggit.dev/user_avatar/ziggit.dev/adria/32/605_2.png) [@adria](https://ziggit.dev/u/adria)\
**Post date:** [April 16, 2026, 4:51am UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/23 "2026-04-16T04:51:09Z")

</div>

Hi! Thank for your encouraging words.  
You’re right, `.eval()` is misleading, since the user might think there’s some kind of lazy evaluation or something…  
I need to find a better name and `.ok()` might be it. I don’t mind breaking the API, it’s explicitly stated in the README. And I don’t think people are using Zig expect a smooth developer experience, once you choose to use Zig, you assume things will break 😛  
I will think more about it. Thanks again 🙂

---

<div class="post-metadata">

**Author:** ![tgirod](https://ziggit.dev/user_avatar/ziggit.dev/tgirod/32/3744_2.png) [@tgirod](https://ziggit.dev/u/tgirod)\
**Post date:** [May 26, 2026, 2:19pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/24 "2026-05-26T14:19:05Z")

</div>

@adria thanks for your work on zignal! I’m currently using it to export gif images.

I saw you are working on supporting animated images in the master branch. Do you plan to backport this code into the 0.10.0 branch with zig 0.16 compatibility?

---

<div class="post-metadata">

**Author:** ![Quin](https://ziggit.dev/user_avatar/ziggit.dev/quin/32/7147_2.png) [@Quin](https://ziggit.dev/u/Quin)\
**Post date:** [May 26, 2026, 2:39pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/25 "2026-05-26T14:39:46Z")

</div>

Just dropping in to say I love this library. It has so many features that I’m still just digging through it to find new things to add to txt2img, and the built-in CLI is super nice too. Thanks for all your incredible work!

---

<div class="post-metadata">

**Author:** ![adria](https://ziggit.dev/user_avatar/ziggit.dev/adria/32/605_2.png) [@adria](https://ziggit.dev/u/adria)\
**Post date:** [May 26, 2026, 8:56pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/26 "2026-05-26T20:56:06Z")

</div>

Hi, honestly, I wasn’t planning on it, but if it’s a blocker to you, I might try to find some time. I think 0.17 will be released soon, though.

---

<div class="post-metadata">

**Author:** ![adria](https://ziggit.dev/user_avatar/ziggit.dev/adria/32/605_2.png) [@adria](https://ziggit.dev/u/adria)\
**Post date:** [May 26, 2026, 8:56pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/27 "2026-05-26T20:56:28Z")

</div>

Thank you so much! I am glad you find it useful 🙂

---

<div class="post-metadata">

**Author:** ![tgirod](https://ziggit.dev/user_avatar/ziggit.dev/tgirod/32/3744_2.png) [@tgirod](https://ziggit.dev/u/tgirod)\
**Post date:** [May 26, 2026, 9:12pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/28 "2026-05-26T21:12:47Z")

</div>

That would be great, but I don’t want to put more work on your plate … maybe I can try to do it.

---

<div class="post-metadata">

**Author:** ![tgirod](https://ziggit.dev/user_avatar/ziggit.dev/tgirod/32/3744_2.png) [@tgirod](https://ziggit.dev/u/tgirod)\
**Post date:** [May 27, 2026, 9:29am UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/29 "2026-05-27T09:29:50Z")

</div>

Nevermind, it looks like the master branch compiles with 0.16 !

---

<div class="post-metadata">

**Author:** ![adria](https://ziggit.dev/user_avatar/ziggit.dev/adria/32/605_2.png) [@adria](https://ziggit.dev/u/adria)\
**Post date:** [May 27, 2026, 9:53am UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/30 "2026-05-27T09:53:21Z")

</div>

ah, right, what doesn’t compile on 0.16 are the Python bindings (`zig build python-bindings`)

---

<div class="post-metadata">

**Author:** ![adria](https://ziggit.dev/user_avatar/ziggit.dev/adria/32/605_2.png) [@adria](https://ziggit.dev/u/adria)\
**Post date:** [October 14, 2026, 3:57pm UTC](https://ziggit.dev/t/new-image-processing-library-zignal/4011/31 "2026-10-14T15:57:40Z")

</div>

Zignal 0.11.0 is out, now on Zig 0.17.0!

> **[Release zignal 0.11.0 · arrufat/zignal](https://github.com/arrufat/zignal/releases/tag/0.11.0)**
>
> Zignal 0.11.0
> This release moves zignal to Zig 0.17.0, runs filters, transforms and codecs in parallel through std.Io, adds vector fonts with text layout, QR codes, CMYK and new animated codecs, an...

The big change: most operations now take an `io: Io` and split their work into row bands, so filters, codecs and resizing run in parallel on a thread pool. Without threads (e.g. on WASM) the same code runs serially, with identical results.

Other bits:

- JPEG and PNG got a lot faster (on par with libjpeg-turbo and libpng)
- TrueType/OpenType fonts and text layout
- QR codes, CMYK JPEGs, BMP and animated GIF/WebP/JPEG XL
- The API is namespaced now (`image.*`, `canvas.*`, `matrix.*`…), so expect some breakage

@tgirod animated GIF export is in this release, and it works on a stable Zig now.

@mnemnion I ended up dropping `eval()` altogether: matrix ops return errors directly, so a plain `try` works, and the deferred-error chain lives in `matrix.Chain` with `toOwned()`.

0.12 dev continues on Zig master. Feedback welcome as always!

[Previous page](https://ziggit.dev/t/new-image-processing-library-zignal/4011.md?page=1)
