{"id":24904935,"url":"https://github.com/okaneco/rscolorq","last_synced_at":"2025-10-16T16:31:24.826Z","repository":{"id":38132431,"uuid":"300949157","full_name":"okaneco/rscolorq","owner":"okaneco","description":"Spatial color quantization in Rust","archived":false,"fork":false,"pushed_at":"2021-03-30T23:09:10.000Z","size":736,"stargazers_count":61,"open_issues_count":3,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-22T07:23:25.539Z","etag":null,"topics":["color-palette","color-quantization","dithering","image-processing","rust","scolorq","spatial-color-quantization"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/okaneco.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-10-03T18:27:41.000Z","updated_at":"2024-08-21T12:25:16.000Z","dependencies_parsed_at":"2022-07-09T13:16:03.689Z","dependency_job_id":null,"html_url":"https://github.com/okaneco/rscolorq","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okaneco%2Frscolorq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okaneco%2Frscolorq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okaneco%2Frscolorq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okaneco%2Frscolorq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/okaneco","download_url":"https://codeload.github.com/okaneco/rscolorq/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236735028,"owners_count":19196362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["color-palette","color-quantization","dithering","image-processing","rust","scolorq","spatial-color-quantization"],"created_at":"2025-02-01T23:46:04.781Z","updated_at":"2025-10-16T16:31:24.429Z","avatar_url":"https://github.com/okaneco.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rscolorq\n[![Build Status](https://img.shields.io/github/workflow/status/okaneco/rscolorq/Rust%20CI/master)](https://github.com/okaneco/rscolorq)\n[![Crates.io](https://img.shields.io/crates/v/rscolorq.svg)](https://crates.io/crates/rscolorq)\n[![Docs.rs](https://docs.rs/rscolorq/badge.svg)](https://docs.rs/rscolorq)\n\n![dithered mountains](gfx/mountain-colors6-repeats4.png)\n\nRust port of Derrick Coetzee's [`scolorq`][scolorq], based on the 1998 paper\n\"On spatial quantization of color images\" by Jan Puzicha, Markus Held, Jens\nKetterer, Joachim M. Buhmann, \u0026 Dieter Fellner. *Spatial quantization* is\ndefined as simultaneously performing halftoning (dithering) and color\nquantization (limiting the colors in an image). For more information, visit\n[the original implementation's website][scolorq].\n\nThe algorithm is excellent for retaining image detail and minimizing visual\ndistortions for color palettes in the neighborhood of 4, 8, or 16 colors,\nespecially as the image size is reduced. It combines limiting the color palette\nand dithering the image into a simultaneous process as opposed to sequentially\nlimiting the colors then dithering. Colors are chosen based on their context in\nthe image, hence the \"spatial\" aspect of spatial color quantization. As in\n[Pointillism][Pointillism], the colors are selected based on their neighbors to\nmix as an average illusory color in the human eye.\n\n[scolorq]: http://people.eecs.berkeley.edu/~dcoetzee/downloads/scolorq/\n[Pointillism]: https://en.wikipedia.org/wiki/Pointillism#Gallery\n\nTo use as a library, add the following to your `Cargo.toml`; add the\n`palette_color` feature to enable Lab color quantization. Executable builds can\nbe found at https://github.com/okaneco/rscolorq/releases.\n\n\n```toml\n[dependencies.rscolorq]\nversion = \"0.2\"\ndefault-features = false\n```\n\n## Examples\n\n*Images are best viewed at 100% magnification.*\n\n### **1) Mandrill**\n\n![4 quantized mandrills](/gfx/mandrill-montage.png)  \n*Top row: Original image, RGB 2 colors*  \n*Bottom row: RGB 4 colors, RGB 8 colors*  \n\n```\nrscolorq -i mandrill.jpg -o mandrill-rgb2.png -n 2 --auto -s 0 --iters 5\nrscolorq -i mandrill.jpg -o mandrill-rgb4.png -n 4 --auto -s 0 --repeats 3\nrscolorq -i mandrill.jpg -o mandrill-rgb8.png -n 8 --auto -s 0 --iters 5\n```\n\nThe `--iters` and `--repeats` options can be used to increase their values over\nthe default to improve the quality of output. `--auto` sets the dithering\nlevel based on the image size and desired palette size. The `--seed` or `-s`\noption sets the random number generator seed; otherwise, it's seeded randomly.\n\n### **2) Palette swatches and fixed palette**\n\nPalette swatches can be generated by passing `--op` plus a filename. `--width`\nand `--height` can be passed to specify the width and height of the resulting\npalette image. The following swatches are the colors that comprise 4 and 8 color\ndithered images in the bottom row of the previous image.\n\n![4 color swatch](/gfx/mandrill-rgb4-pal.png)  \n![8 color swatch](/gfx/mandrill-rgb8-pal.png)  \n\n```\nrscolorq -i mandrill-resize.jpg --op mandrill-rgb4-pal.png -n 4 --auto -s 0 --repeats 3\nrscolorq -i mandrill-resize.jpg --op mandrill-rgb8-pal.png -n 8 --auto -s 0 --iters 5 -p\n```\n\nPassing the `--print` or `-p` flag will print the hexadecimal colors to the\nterminal as seen in the second example above. If no `--output` or `-o` is\npassed, the dithered image will not be saved to a file.\n\n```\nb5c970,191821,b7cbe7,6d7f7b,5db7f0,4e5936,f05131,939bcc\n```\n\n### ***Custom color palette***\n\nYou can supply your own palette to dither with by passing `--colors` or\n`-c` followed by a list of hexadecimal colors as in the following example.\n\n![2 tone mandrill](/gfx/mountain.jpg)  \n*Original image on the left, fixed palette on the right.*\n\n```\nrscolorq -i scenic.jpg -o mountain-pal.png -c FFBF82,09717E --auto -s 0 --iters 5`\n```\n\n### **3) Gradients**\n\n![4 quantized rainbow gradients](/gfx/rainbow-montage.png)  \n*Top row: Original image, RGB 4 colors, RGB 8 colors.*  \n*Bottom row: Lab 4 colors, Lab 8 colors.*  \n\n```\nrscolorq -i rainbow.png -o rainbow-rgb4.png -n 4\nrscolorq -i rainbow.png -o rainbow-rgb8.png -n 8 --iters 8 --repeats 2\nrscolorq -i rainbow.png -o rainbow-lab4.png -n 4 --lab\nrscolorq -i rainbow.png -o rainbow-lab8.png -n 8 --lab --iters 8 --repeats 2\n```\n\n![3 greyscale gradients](/gfx/gradient-orig-3-5.png)  \n*Left to right: Original image, 2 colors filter size 3, 2 colors filter size 5.*\n\n## **Features**\n- use RGB or Lab color space for calculations\n- option to dither based on fixed color palette supplied by the user\n- seedable RNG for reproducible results\n- print the palette colors to the command line in hexadecimal\n- create a palette swatch image from the dither colors\n\n## **Limitations**\n\n### It's \"slow\"\n- Larger images or images with smooth transitions/gradients will take longer.\nHigher palette sizes will take longer.\n- The algorithm is suited towards retaining detail with smaller color palettes.\nYou can still use it on larger images but be aware it's not close to real-time\nunless the image is small.\n\n### Filter size 1x1\n- Doesn't produce an image resembling the input, nor does the original.\n\n### Filter size 5x5\n- Doesn't always converge.\n- I'm unsure if this is an error in this implementation or a problem with the\nrandom number generator being used. The original implementation may take a while\nbut eventually completes with filter size 5.\n- *Any help on this would be appreciated.*\n\n## **Troubleshooting**\nIf you get an invalid color error or hex color length error with the command\nline tool, try enclosing the color string in quotes.\n\nFor example, instead of `-c 000000,ffffff` use `-c '000000,ffffff'`.\n\n## **License**\nThis crate is licensed under either\n- the [MIT License](LICENSE-MIT), or\n- the [Apache License (Version 2.0)](LICENSE-APACHE)\n\nat your option.\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n\n*Copyright of the original images is property of their respective owners.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokaneco%2Frscolorq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fokaneco%2Frscolorq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokaneco%2Frscolorq/lists"}