An extensive, fast, and accurate command-line image dithering tool.

didder

go reportcard

didder is an extensive, fast, and accurate command-line image dithering tool. It is designed to work well for both power users as well as pipeline scripting. It is backed by my dithering library, and is unique in its correctness and variety of dithering algorithms. No online or offline tool I know of provides as many options, while being correct (linearizing the image).

Types of dithering supported

  • Random noise (in grayscale and RGB)
  • Ordered Dithering
    • Bayer matrix of any size (as long as dimensions are powers of two)
    • Clustered-dot - many different preprogrammed matrices
    • Some unusual horizontal or vertical line matrices
    • Yours? You can provide your own ordered dithering matrix in JSON format
  • Error diffusion dithering
    • Simple 2D
    • Floyd-Steinberg, False Floyd-Steinberg
    • Jarvis-Judice-Ninke
    • Atkinson
    • Stucki
    • Burkes
    • Sierra/Sierra3, Sierra2, Sierra2-4A/Sierra-Lite
    • Steven Pigeon
    • Yours? You can provide your own error diffusion matrix in JSON format

More methods of dithering are being worked on, such as Riemersma, Yuliluoma, and blue noise. If you'd like to help out with development of those methods, or request a new one, please make an issue in my dither library repo, not this one.

Features

  • Set palette using RGB tuples, hex codes, number 0-255 (grayscale), or SVG color names
  • Optionally recolor image with a different palette after dithering
  • Set dithering strength
  • Image is automatically converted to grayscale if palette is grayscale
  • Force image to grayscale with --grayscale
  • Change image saturation, brightness, or contrast before dithering
  • Read EXIF rotation tags by default (disabled with --no-exif-rotation)
  • Downscale image before dithering, keeping aspect ratio
  • Upscale image after dithering, without producing artifacts
  • Supports input image of types JPEG, GIF (static), PNG, BMP, TIFF
  • Output to PNG or GIF
  • Process multiple images with one command
  • Combine multiple images into an animated GIF
  • Uses all CPU cores when possible
  • Support images with transparency (alpha channel is kept the same)

Installation

Binary

Download a binary from the releases page. On Unix-based systems you will have to make the file executable with chmod +x . You can rename the file to just didder for easy access, and move it to /usr/local/bin/.

On Windows you will have to open a terminal or cmd window in the same directory as the EXE file, or add it to your PATH.

Make sure to click "Watch" in the top right, then "Custom" > "Releases" to get notified about new releases!

Homebrew

If you use Homebrew, you can install didder through the my personal tap.

brew tap makeworld-the-better-one/tap
brew install didder

You can update it with:

brew upgrade didder

From source

Requirements

  • Go 1.14 or later
  • GNU Make

Please note the Makefile does not intend to support Windows, and so there may be issues.

git clone https://github.com/makeworld-the-better-one/didder
cd didder
# git checkout v1.2.3 # Optionally pin to a specific version instead of the latest commit
make # Might be gmake on macOS
sudo make install # Install binary and man page

macOS users can also use Homebrew to install the latest commit of didder:

brew tap makeworld-the-better-one/tap
brew install --HEAD didder

You can update it with:

brew upgrade --fetch-HEAD didder

Getting started

didder [global options] command [command options] [arguments...]

The best place to learn about how to use didder is the manual. Run man didder, or look at the MANPAGE.md file. If you only read about one flag, read about --strength. It's especially important for bayer dithering of color images.

You can also run didder to see the global options and commands. Each command represents a different dithering algorithm, or set of algorithms. You can see the options for each command with didder help cmd or didder cmd --help.

Here's a fully working command as an example:

didder --palette 'black white' -i input.jpg -o test.png bayer 16x16

This command dithers input.jpg to just use black and white (implicitly converting to grayscale first), using a 16x16 Bayer matrix. The result is written to test.png.

As another example, here's the command used for the image at the top of the README:

didder -i david.png -o david_dithered.png --palette 'black white' --recolor 'black F273FF' --upscale 2 bayer 4x4

If you'd like the replicate this yourself, the input image is available here.

What method should I use?

Generally, using Floyd-Steinberg serpentine dithering will produce results with the fewest artifacts. The command would be:

didder [palette and I/O options] edm --serpentine FloydSteinberg

Playing with the strength of the matrix might also be useful. The example above is at full strength, but sometimes that's too noisy. The command for 80% strength looks like this:

didder --strength 80% [palette and I/O options] edm --serpentine FloydSteinberg

The main reason for using any other dithering algorithm would be

  • Aesthetics - dithering can be a cool image effect, and different methods will produce different and stronger artifacts
  • Speed - error diffusion dithering is sequential and therefore single-threaded. But ordered dithering, like using Bayer, will use all available CPUs, which is much faster.

If you want to see examples of the different dithering algorithms, you can look at this directory. Or try them out yourself!

License

This project is licensed under the GPL v3.0. See the LICENSE file for details.

Comments
  • Possible corrupt gif generated

    Possible corrupt gif generated

    via https://github.com/skyjake/lagrange/issues/353

    I generated a GIF with the following didder options: -f gif -x 600 -p 'tomato orange gold lightseagreen cornflowerblue mediumpurple black ivory' edm --serpentine Simple2D. This image won't display properly in Lagrange. Apparently running GraphicsMagick on the image fixed it (per the linked discussion) but this process adds 48 bytes.

    Strangely I am able to view the image just fine in a couple of other programs. Maybe they are more forgiving than std_image (used by Langrange), or it is possible that the generated image uses a format that is technically valid but is not widely supported. The fact that GraphicsMagick adds bytes and this "fixes" it makes me think that something important is missing from the image data.

    I've attached the two example images.

    Original: test

    Fixed: test-fixed

  • Choose which colorspace to use for proximity

    Choose which colorspace to use for proximity

    Sometimes the dithering seems to not get the gist of a color region. For example, in the following images, look at the shadowy region around the demon's head.

    Here's the original image:

    image before dither

    And here's the output after this command was run:

    didder --palette "#242022 #f5ede6 #eb4e48 #b18661" -i krampus.jpg -o test.png -c size edm --serpentine FloydSteinberg
    

    image after dither

    To my human eyes, the shadow region behind and above the demon's head seems like it would be described with a mix of red and black. However, probably due to it being a mid-brightness color, it is dithered as a mixture of brown and black, meaning it loses the red tones.

    My hunch is that this effect is due to the colorspace used. Perhaps if the colorspace were treated as HSV rather than RGB, the colors would be considered closer to red than brown.

    Additionally, it might help to use a form of gamma-correction to find the difference between colors, to better represent the way that they are perceived to human eyes.

  • Stuck on 'required flags

    Stuck on 'required flags "palette, out, in" not set.'

    Hi!

    I'm sorry if this is not the right way to reach out. Couldn't find any info on this in the docs sadly.

    I'm not able to get didder to do anything with any image. It keeps giving me back the line from the title. 'required flags "palette, out, in" not set.'

    Any tips on how to get past this? Added the didder.exe to my PATH as specified, so it shouldn't be that.

    Thanks!

  • Edm command doesn't work

    Edm command doesn't work

    Command i'm using is didder -i david.png -o david_dithered.png --palette "black white" --recolor "black F273FF" --upscale 2 edm Sierra2

    and I get couldn't process argument as matrix name, inline JSON, or path to accessible JSON file

    OS: Windows 10 Home Architecture: x86-64

  • Best settings for light weight/size images

    Best settings for light weight/size images

    Hi,

    I plan to use didder to convert images in my blog to gain speed thus reducing image weight/size. What would be the best settings/options to use in didder, keeping colors or black and white?

    Thank you.

  • Support images with alpha channel

    Support images with alpha channel

    Depends on https://github.com/makeworld-the-better-one/dither/issues/8

    --recolor would then support RGBA colors, like 123,123,123,123. This would allow the alpha channel of specific palette colors to be changed, along with the other color channels. The RGB part of the recolor would have to apply to the un-premulted colors in the image.

    This RGBA input is treated as unpremulted.

    Attempting to output to GIF would raise an error.

  • Minor copy edits

    Minor copy edits

    • Em dashes or die!
    • Clarifies pre-dither adjustments in the tips section (if they're going to only read one thing this is it!)
    • Minor grammatical adjustments
    • Removed "TODO" in examples, there's a nice valid example and just add more later? Feels more unpolished than it needs to be with this label.
  • FrozenError error on MacOS install

    FrozenError error on MacOS install

    Hi there,

    After I successfully tap into brew tap makeworld-the-better-one/tap

    I get this error:

    brew install didder ==> Downloading https://github.com/makeworld-the-better-one/didder/archive/v1.1.0.tar.gz ==> Downloading from https://codeload.github.com/makeworld-the-better-one/didder/tar.gz/refs/tags/v1.1.0 ##O=# # ==> Installing didder from makeworld-the-better-one/tap Error: An exception occurred within a child process: FrozenError: can't modify frozen class

    I'm on macOS Monterey 12.6, Macbook Air M2

    Please assist.

  • Error when upscaling GIF

    Error when upscaling GIF

    Iā€™m trying to 2x upscale a 25 frames 800x800 gif but it says imagine [image] block is out of bounds.

    This bug comes from the gif library, specifically this line. Why is it triggering in this case?

    • [ ] Reproduce this
  • Parallelize error diffusion dithering for multiple images

    Parallelize error diffusion dithering for multiple images

    Error diffusion dithering is inherently sequential. But it could be parallelized when multiple images are given as input, by dithering multiple images at once. It would require a large refactor.

    • Error channel for passing errors up to be handled
    • Collect open files somewhere for closing
  • Auto-pick colours from image for use in the palette

    Auto-pick colours from image for use in the palette

    Would be cool to auto-choose x number of colours from the input image using colour quantization as defined by a single integer set as the --palette value. For example --palette 5 would choose the 5 best colours from the source image and dither accordingly.

    Additionally, don't limit users to a minimum of 2 values! By allowing people to select a single average colour the application now has a bonus feature of spitting out average coloured images. It's not a bug, it's a feature!

Image - This repository holds supplementary Go image librariesThis repository holds supplementary Go image libraries

Go Images This repository holds supplementary Go image libraries. Download/Insta

Jan 5, 2022
darkroom - An image proxy with changeable storage backends and image processing engines with focus on speed and resiliency.
darkroom - An image proxy with changeable storage backends and image processing engines with focus on speed and resiliency.

Darkroom - Yet Another Image Proxy Introduction Darkroom combines the storage backend and the image processor and acts as an Image Proxy on your image

Dec 6, 2022
An API which allows you to upload an image and responds with the same image, stripped of EXIF data

strip-metadata This is an API which allows you to upload an image and responds with the same image, stripped of EXIF data. How to run You need to have

Nov 25, 2021
Easily customizable Social image (or Open graph image) generator

fancycard Easily customizable Social image (or Open graph image) generator Built with Go, Gin, GoQuery and Chromedp Build & Run Simply, Clone this rep

Jan 14, 2022
Imgpreview - Tiny image previews for HTML while the original image is loading
Imgpreview - Tiny image previews for HTML while the original image is loading

imgpreview This is a Go program that generates tiny blurry previews for images t

May 22, 2022
A lightning fast image processing and resizing library for Go

govips A lightning fast image processing and resizing library for Go This package wraps the core functionality of libvips image processing library by

Jan 8, 2023
Go package for fast high-level image processing powered by libvips C library

bimg Small Go package for fast high-level image processing using libvips via C bindings, providing a simple programmatic API. bimg was designed to be

Jan 2, 2023
Fast, simple, scalable, Docker-ready HTTP microservice for high-level image processing

imaginary Fast HTTP microservice written in Go for high-level image processing backed by bimg and libvips. imaginary can be used as private or public

Jan 3, 2023
Fast Image Convolutions (Gaussian) Blur

Usage package main import ( "image" "image/jpeg" "os" "github.com/0xc0d/ficblur" ) func main() { imageFile, err := os.Open("img.jpeg") panicN

Feb 5, 2022
A lightweight and easy to use tool for deflickering timelapse image sequences.
A lightweight and easy to use tool for deflickering timelapse image sequences.

Simple Deflicker A minimalist, lightning-fast and easy to use tool for deflickering image sequences such as timelapses. It's still in its early stages

Aug 12, 2022
šŸ” Go tool for LSB steganography, capable of hiding any file within an image.
šŸ” Go tool for LSB steganography, capable of hiding any file within an image.

stegify Overview stegify is a simple command line tool capable of fully transparent hiding any file within an image or set of images. This technique i

Jan 1, 2023
Faster than the fastest in the world pixel-by-pixel image difference tool.

imgdiff Faster than the fastest in the world pixel-by-pixel image difference tool. Why? imgdiff isn't as fast as a tool like this should be and I'm no

Dec 21, 2022
Tool to scan a container image's rootfs

image-rootfs-scanner A tool to pull and scan the rootfs of any container image for different binaries. It started out as a means of finding "restricte

Mar 30, 2022
Go package captcha implements generation and verification of image and audio CAPTCHAs.
Go package captcha implements generation and verification of image and audio CAPTCHAs.

Package captcha āš ļø Warning: this captcha can be broken by advanced OCR captcha breaking algorithms. import "github.com/dchest/captcha" Package captch

Dec 30, 2022
This command line converts .html file into .html with images embed.

embed-html This command line converts .html file into .html with images embed. Install > go get github.com/gonejack/embed-html Usage > embed-html *.ht

Oct 6, 2022
Image processing library and rendering toolkit for Go.

blend Image processing library and rendering toolkit for Go. (WIP) Installation: This library is compatible with Go1. go get github.com/phrozen/blend

Nov 11, 2022
Go package for decoding and encoding TARGA image format

tga tga is a Go package for decoding and encoding TARGA image format. It supports RLE and raw TARGA images with 8/15/16/24/32 bits per pixel, monochro

Sep 26, 2022
Storage and image processing server written in Go
Storage and image processing server written in Go

Mort An S3-compatible image processing server written in Go. Still in active development. Features HTTP server Resize, Rotate, SmartCrop Convert (JPEG

Jan 7, 2023
Image resizing in pure Go and SIMD

rez Package rez provides image resizing in pure Go and SIMD. Download: go get github.com/bamiaux/rez Full documentation at http://godoc.org/github.com

Dec 11, 2022