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 ...”
“翻译:我确信我想到了一条美妙的评论,可惜这里的空白处太小,只有动态里才写得下。”
—— 复制自我原本发送并从未删除的评论。
cargo install quadim -F build-bin
Installation: Run (Sorry I can't provide binaries)
Usage & Gallery
-
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.
-
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.)
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
:
Run (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 largeborder_width
or an abruptborder_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?
-
Use clap to parse command line input; Use src-dst-clarifier to handle source-to-destination file mapping; Use threadpool to parallel processing.
-
Analyze Pass
-
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
. -
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) -
Attempts to merge all sub-blocks.
There are two cases that can be merged:
- The maximum depth is reached, all pixels in this area will always merged, averaged and cached.
- 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 withAnalyzeParams::thres_
. Merge if "fluctuation" is small enough, then calculate the average and cache it.
There are two cases that cannot be merged:
- The inverse of case two.
- Sub-blocks of sub-blocks of sub-blocks... cannot be made into merged.
-
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.) -
After the traversal complete, the quadtree information has been fully recorded in canvas. Since no data is double-counted, so Quadim is very efficient.
-
-
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
- When drawing a large ellipse/circle, it gets cropped. (See image-rs/imageproc#519)
Appendix: Exit Code Meanings
- Success.
- Some errors.
- Too many errors.
- Fatal.