Expand description
A sixel library for encoding images.
§Basic Usage
§Simple Encoding
use a_sixel::PaletteBuilder;
use a_sixel::SixelEncoder;
use a_sixel::dither::Dither;
use image::RgbaImage;
let img = RgbaImage::new(100, 100);
println!(
"{}",
SixelEncoder::new(PaletteBuilder::BitMergeBest, Dither::Sierra).encode(img)
);§Loading and Encoding an Image File
use a_sixel::PaletteBuilder;
use a_sixel::SixelEncoder;
use a_sixel::dither::Dither;
// Load an image from file
let image = image::open("examples/transparent.png").unwrap().to_rgba8();
// Encode with 256 colors and Sierra dithering
let encoder = SixelEncoder::new(PaletteBuilder::KMeans, Dither::Sierra);
let sixel_output = encoder.encode(image);
println!("{}", sixel_output);§Custom Palette Size and Dithering
use a_sixel::PaletteBuilder;
use a_sixel::SixelEncoder;
use a_sixel::dither::Dither;
let image = image::open("examples/transparent.png").unwrap().to_rgba8();
// Use 16 colors with no dithering for faster encoding
let encoder = SixelEncoder::new(PaletteBuilder::Bit, Dither::None);
let sixel_output = encoder.encode_with_palette_size(image, 16);
println!("{}", sixel_output);§Transparency
By default, a-sixel handles transparency by setting any fully-transparent
pixels to all-bits-zero. This translates to a transparent pixel in most
sixel implementations, but some terminals may not support this.
Sixel does not natively support partial transparency, but this library does
have some support for rendering images as if partial transparency was
supported. If the partial-transparency feature is enabled, a-sixel will
query the terminal and attempt to determine the background color. Partially
transparent pixels will then be blended with this background color before
encoding. Note that with this approach, changing the terminal background
color will not update partially transparent pixels to match. You will need
to re-encode the image if the background color changes.
§Choosing a PaletteBuilder
- I want good quality:
- I’m time constrained:
- I’m really time constrained and can sacrifice a little quality:
- Use
PaletteBuilder::BitwithDither::None.
- Use
For a more detailed breakdown, here’s the encoders by average speed and quality against the test images (speed figures will vary) at 256 colors with Sierra dithering:
| Algorithm | MSE | DSSIM | PHash Distance | Mean ΔE | Max ΔE | ΔE >2.3 | ΔE >5.0 | Execution Time (ms) |
|---|---|---|---|---|---|---|---|---|
| adu | 15.04 | 0.0052 | 8.86 | 1.79 | 12.80 | 31.8% | 4.4% | 1448 |
| bit | 35.82 | 0.0132 | 31.14 | 3.16 | 11.03 | 64.5% | 15.1% | 468 |
| bit-merge-low | 10.67 | 0.0038 | 13.97 | 1.95 | 9.98 | 32.4% | 2.2% | 855 |
| bit-merge | 10.37 | 0.0037 | 13.48 | 1.89 | 10.03 | 31.0% | 2.2% | 1034 |
| bit-merge-better | 10.30 | 0.0037 | 13.07 | 1.85 | 10.22 | 30.6% | 2.2% | 1301 |
| bit-merge-best | 10.28 | 0.0037 | 13.59 | 1.83 | 10.20 | 30.5% | 2.2% | 1532 |
| focal | 31.10 | 0.0091 | 19.72 | 3.34 | 8.41 | 73.9% | 13.1% | 821 |
| k-means | 10.07 | 0.0036 | 13.28 | 1.80 | 10.14 | 29.1% | 2.2% | 3175 |
| k-medians | 17.22 | 0.0067 | 19.10 | 2.56 | 9.98 | 50.8% | 4.7% | 9088 |
| median-cut | 19.64 | 0.0059 | 16.45 | 2.24 | 10.36 | 42.2% | 5.9% | 740 |
| octree | 54.48 | 0.0148 | 26.03 | 3.89 | 12.49 | 78.6% | 25.4% | 754 |
| wu | 17.89 | 0.0068 | 21.03 | 2.34 | 10.24 | 46.3% | 5.1% | 1984 |
Note: Execution time includes the time taken to compute error statistics - this is non-trivial. For example, exclusive of error statistics computation, bit-no-dither takes <100ms on average. Performance figures will vary based on machine, etc. They are only useful for comparing algorithms against each other within this dataset.
Here’s the encoders at 16 colors with Sierra dithering:
| Algorithm | MSE | DSSIM | PHash Distance | Mean ΔE | Max ΔE | ΔE >2.3 | ΔE >5.0 | Execution Time (ms) |
|---|---|---|---|---|---|---|---|---|
| adu | 118.90 | 0.0364 | 40.86 | 4.04 | 18.38 | 65.7% | 33.8% | 357 |
| bit | 178.47 | 0.0490 | 59.79 | 5.53 | 16.61 | 89.0% | 51.4% | 325 |
| bit-merge-low | 95.61 | 0.0302 | 41.59 | 3.97 | 16.26 | 67.4% | 31.4% | 631 |
| bit-merge | 94.53 | 0.0302 | 41.48 | 3.95 | 16.15 | 67.0% | 31.3% | 800 |
| bit-merge-better | 96.11 | 0.0299 | 41.55 | 3.96 | 16.17 | 67.9% | 31.4% | 1078 |
| bit-merge-best | 95.44 | 0.0297 | 41.69 | 3.96 | 16.46 | 67.0% | 31.4% | 1297 |
| focal | 345.08 | 0.0585 | 56.66 | 7.23 | 16.65 | 95.6% | 74.8% | 433 |
| k-means | 99.36 | 0.0309 | 42.83 | 3.99 | 16.39 | 66.9% | 31.4% | 702 |
| k-medians | 173.95 | 0.0533 | 59.62 | 5.57 | 16.23 | 90.8% | 49.7% | 7255 |
| median-cut | 164.52 | 0.0374 | 45.28 | 4.68 | 16.72 | 73.7% | 42.3% | 395 |
| octree | 459.37 | 0.0845 | 75.03 | 7.69 | 18.87 | 98.3% | 73.5% | 477 |
| wu | 125.84 | 0.0386 | 50.52 | 4.48 | 16.70 | 74.5% | 39.2% | 929 |
Modules§
- adu
adu - Use Adaptive Distributive Units to “learn” the image’s color properties and select palette entries.
- bit
- Encodes a palette by bucketing bit ranges into a power of two number of buckets. This is very fast and produces ok results for most images at larger palette sizes (e.g. 256).
- bitmerge
bit-merge - Uses
BitSixelEncoderwith k-means and agglomerative merging to build a palette. - dither
- A collection of various dithering algorithms that can be used with the
SixelEncoderto dither the result. - focal
focal - Spectral-residual peak isolation for palette generation.
- kmeans
k-means - Use k-means clustering to determine a palette for the image.
- kmedians
k-medians - Uses k-medians to build a palette of colors.
- median_
cut median-cut - https://en.wikipedia.org/wiki/Median_cut
- octree
octree - Uses an octree to build a palette from an image.
- wu
wu - Uses Wu’s quantization algorithm to build a palette from an image.
Structs§
- Sixel
Encoder - The main type for performing sixel encoding.
Enums§
- Palette
Builder - The palette building algorithm to use for color quantization.