Fastest image quadtree stylization implementation to date, capable of hundreds of fps and avoiding ugly non-squares.

Overview

Quadim

Fastest image quadtree stylization implementation to date, capable of hundreds of fps and avoiding ugly non-squares.

简体中文

如果你是从B站来的……
“Listen to the wind, the wind is surging, here is not a place to stay ...”

“翻译:我确信我想到了一条美妙的评论,可惜这里的空白处太小,只有动态里才写得下。”

—— 复制自我原本发送并从未删除的评论。

Installation: Run cargo install quadim -F build-bin

(Sorry I can't provide binaries)

Usage & Gallery

  1. Don't worry about messing your workspace. (Thanks to my another project src-dst-clarifier)

    > quadim example.jpg    # A file named like "example.jpg-A01123-0456-0789.png" will generate.
    
    > quadim ./frames       # A directory named like "frame-A01123-0456-0789" will generate.
  2. No! I am too lazy to write a tutorial, try it yourself please ╰( ̄ω ̄o)

    Fastest image quadtree stylization implementation to date, capable of hundreds of fps and avoiding ugly non-squares.
    
    Usage: quadim.exe [OPTIONS] <IMAGE_OR_DIR>
    
    Arguments:
      <IMAGE_OR_DIR>  The image to process, or all images in a directory to process
    
    Options:
      -o, --output <IMAGE_OR_DIR>        Leave blank to automatically create a time-based named DST, or specify manually
      -r, --ratio <SLICING_RATIO>        Specifies how to slice the image into sub-blocks [default: 1:1]
      -d, --depth <MAX_DEPTH>            The maximum depth of the quadtree [default: 8]
      -Y, --thres-ay <THRES_AY>          Thresholding on Alpha and Luma channels [default: 20]
      -C, --thres-cbcr <THRES_CBCR>      Thresholding on the other two Chrominance channels. Notice! The tests are performed sequentially! [default: 2]
          --merge <MERGE_METHOD>         Specifies the algorithm to use for merging tests [default: st-dev] [possible values: range, st-dev]
      -s, --shape <BRUSH>                Specifies the shape used to depict each node on the quadtree [default: rect] [possible values: rect, circle, cross]
      -B, --bg-color <BG_COLOR>          The background color of the fill (if required) [default: white]
      -S, --stroke-color <STROKE_COLOR>  The color of the stroke [default: black]
      -W, --stroke-width <STROKE_WIDTH>  The width of the stroke [default: 0]
      -P, --parallel <PARALLELISM>       Specifies the number of threads to use. The default is the number of CPU logical cores
          --buffer <BUFFER_SIZE>         The size of the buffer [default: 33177600]
          --errors <MAX_ERRORS>          Error count, when this many errors have occurred, Quadim will terminate early [default: 5]
      -h, --help                         Print help (see more with '--help')
      -V, --version                      Print version
    

    (See also full help.)

Run quadim ./img/4~3/ -o ./img/out-4~3/ --ratio 4:3 --stroke-width 2:

Run quadim ./img/18~9/ -o ./img/out-18~9/ --ratio 18:9 --depth 3 --stroke-width 30:

Run quadim ./img/3~4/ -o ./img/out-3~4/ --ratio 3:4 --depth 6 --shape circle --bg-color transparent:

(I own the copyright of these photos, please don't abuse them(づ ̄3 ̄)づ╭ ~)

Use in my own projects?

Of course you can, all functions are packaged. A word of caution though, no production stability guarantees. (Because I haven't learned how to guarantee it yet :P)

In addition, the documentation is still being improved. Focus on analyze() and render(), that's the all you need to generate quad-images.

Feature List

  • Multithread! Fastest implementation to date
  • Process images in RGBA-8 format.
  • Merge tests in YCbCr instead of RGB space.
  • Since there is no antialiasing, only the left and top borders are actually drawn when --shape rect --border-width N (N > 0) rendering parameters are provided. It is more noticeable when specifying a large border_width or an abrupt border_color.
  • For color parameters: you can pass in DarkSlateGray, hsla(168, 100%, 50%, 1), etc. all colors that can be written in CSS. (Thanks to csscolorparser)

Roadmap

  • 🔥 Allows writing your own brush styles, such as a cross that rotates over time, spots of light that move to the rhythm of the music, filter the specified color in HSL, etc.
  • Completely separate analysis and rendering, allowing direct access to the quadtree binary format...
  • More friendly CLI: Allow multiple images to be passed in at a time, and automatically detect the most appropriate slicing ratio.

How it works?

  1. Use clap to parse command line input; Use src-dst-clarifier to handle source-to-destination file mapping; Use threadpool to parallel processing.

  2. Analyze Pass

    1. Divide the image into sub-slices according to QuadimParams::slicing_ratio. It is often necessary to choose a correct ratio to keep sub-blocks square, such as -r 16:9.

    2. For each sub-block, the quadtree is traversed depth-first according to GenericParams::max_depth. (Here is a line of code that limits the real maximum depth, so the side length of the sub-image is always greater than zero pixel)

    3. Attempts to merge all sub-blocks.

      There are two cases that can be merged:

      1. The maximum depth is reached, all pixels in this area will always merged, averaged and cached.
      2. Check the four pixels in the upper left corner of the four sub-blocks of itself, calculate their standard deviation or range (According to AnalyzeParams::merge_method) and compare with AnalyzeParams::thres_. Merge if "fluctuation" is small enough, then calculate the average and cache it.

      There are two cases that cannot be merged:

      1. The inverse of case two.
      2. Sub-blocks of sub-blocks of sub-blocks... cannot be made into merged.
    4. The additional data structure [CanvasPixel] caches "color average" and "should not merge".

      (The pixel color average is stored at the equivalent of the upper left corner of the sub-block, easily addressing by right shift. [CanvasPixel] is itself one-dimensional, but abstracted to be the same size as the image, two-dimension, which is why the number of pixels of the image cannot be larger than the length of the cache.)

    5. After the traversal complete, the quadtree information has been fully recorded in canvas. Since no data is double-counted, so Quadim is very efficient.

  3. Render Pass

    This time it is the breadth-first traversal of the quadtree. Simply put, it is to take the "color" out of the quadtree and use the "brush" (trait Brush) to draw on the original image.

    Since the size of the new image is guaranteed to be the same as the original image, it can be operated in-place on the original image buffer, requiring no additional memory allocation, which is another element that keeps Quadim efficient.

Known Issues

Appendix: Exit Code Meanings

  1. Success.
  2. Some errors.
  3. Too many errors.
  4. Fatal.
You might also like...
tai (Terminal Ascii Image) tool to convert images to ascii written in Rust
tai (Terminal Ascii Image) tool to convert images to ascii written in Rust

TAI Terminal Ascii Image A tool to convert images to ascii art written in Rust 🦀 Notes This tool is still in development stage. Contributions All Con

Artsy pixel image to vector graphics converter
Artsy pixel image to vector graphics converter

inkdrop inkdrop is an artsy bitmap to vector converter. Command line interface The CLI binary is called inkdrop-cli and reads almost any image bitmap

Automated image compression for efficiently distributing images on the web.

Imager Apparently this project made it into the GitHub Archive Program. About Imager is a tool for automated image compression, and can competitively

Open Graphic Image Writer
Open Graphic Image Writer

Open Graphic Image Writer Documentation You can generate Open Graphic Image dynamically. A CSS-like API. You can generate image by using template imag

A simple image average color extractor written in 🦀 Rust

A simple image average color extractor written in 🦀 Rust

A Simple Image to Ascii converter in Rust
A Simple Image to Ascii converter in Rust

Image to Ascii A Simple Image to Ascii converter in Rust Brief 📖 In my way to learn Rust i decided to make this converter. Challenges 🐢 new to Rust

Rust library for fast image resizing with using of SIMD instructions.

fast_image_resize Rust library for fast image resizing with using of SIMD instructions. CHANGELOG Supported pixel formats and available optimisations:

Experimental vectorized-raster image editor

Sverg Sverg is an experimental image editor that leverages the power of modern hardware so that you can create images as if they were raster images (e

Rust port of the Quite Okay Image format

qoi_rs What is this? A pretty boring Rust translation of qoi. Status What's there Encode & Decode works Results agree with the C implementation for al

Owner
K--A______
K--A______
Lust is a static image server designed to automatically convert uploaded image to several formats and preset sizes

What is Lust? Lust is a static image server designed to automatically convert uploaded image to several formats and preset sizes with scaling in mind.

Harrison Burt 242 Dec 22, 2022
Rust Lean Image Viewer - Fast and configurable image viewer inspired by JPEGView by David Kleiner

Rust Lean Image Viewer - Fast and configurable image viewer inspired by JPEGView by David Kleiner

3top1a 4 Apr 9, 2022
The fastest yes on the planet

The fastest yes on the planet Usage Install pv (Pipe Viewer) to view pipes and witness incredible speeds. Yes. RUSTFLAGS="-C target-cpu=native" cargo

Martin Kröning 3 Oct 9, 2023
Signed distance field font and image command line tool based on OpenCL.

SDFTool Signed distance field font and image command line tool based on OpenCL. Build Windows Run cargo build --release in Visual Studio developer x64

弦语蝶梦 7 Oct 16, 2022
A simple command-line utility (and Rust crate!) for converting from a conventional image file (e.g. a PNG file) into a pixel-art version constructed with emoji

EmojiPix This is a simple command-line utility (and Rust crate!) for converting from a conventional image file (e.g. a PNG file) into a pixel-art vers

Michael Milton 22 Dec 6, 2022
Rust library to get image size and format without loading/decoding

imageinfo-rs Rust library to get image size and format without loading/decoding. The imageinfo don't get image format by file ext name, but infer by f

xiaozhuai, Weihang Ding 47 Dec 30, 2022
Simple image metadata scrubber. Will remove EXIF, XMP and IPTC metadata.

Simple image metadata scrubber. Will remove EXIF, XMP and IPTC metadata.

Jae Lo Presti 12 Nov 29, 2022
Image processing proxy and API, created to allow faster media delivery for the Holaplex storefront.

Description imgopt is an image processing proxy with a very simple API, created to download and dynamically scaledown, convert, and cache different me

Holaplex 5 Nov 3, 2022
Image processing operations

imageproc An image processing library, based on the image library. There may initially be overlap between the functions in this library and those in i

image-rs 512 Jan 8, 2023
Image Compression Algorithm

Image Compression Algorithm ?? A new lossless image compression algorithm. In the newest version the algorithm performs rather good, but manages to su

Hannes 31 May 10, 2022