Skip to content

polyjuicelab/ditto

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ditto logo

ditto

Generative art toolkit powered by nannou. Input an image, output a stylized image.

  • Interfaces: CLI and HTTP Web API (multipart upload)
  • Styles: pixel, posterize, dither, edge, mirror, glitch, cubism, abstract, geometric, kaleidoscope, warp, tessellation, color_field, impressionist, pointillism, watercolor, expressionist, surrealist, pop_art, game_of_life, oil_painting, sketch, cyberpunk
  • TDD-first: unit tests and doctests are required
  • License: AGPL-3.0-only

Philosophy (TDD)

  • Add tests before adding features; tests must define input/output and failure modes.
  • No empty implementations, no TODO placeholders.
  • For invalid user parameters we assert and panic immediately.
  • Keep code small and functional, pass fmt/clippy/doctest.

Build

cargo build

Test

cargo test --all

To run clippy and doctests:

cargo clippy --all-targets --all-features -- -D warnings
cargo test --doc

CLI

# Output PNG (default)
ditto generate --input input.jpg --output out.png --style pixel --pixel-size 8

# Output SVG
ditto generate --input input.jpg --output out.svg --style pixel --pixel-size 8 --format svg

# posterize
ditto generate --input input.jpg --output out.png --style posterize --levels 6

# dither
ditto generate --input input.jpg --output out.png --style dither --dither-levels 2

# edge
ditto generate --input input.jpg --output out.png --style edge --edge-threshold 16

# mirror
ditto generate --input input.jpg --output out.png --style mirror --mirror-tile 8

# glitch
ditto generate --input input.jpg --output out.png --style glitch --glitch-stride 3 --glitch-max-shift 5 --glitch-seed 1 --channel-shift-px 3 --channel-angle-deg 15 --jitter-prob 0.25 --jitter-max-shift 7 --block-size 12 --block-prob 0.15 --block-shift-px 10

# cubism
ditto generate --input input.jpg --output out.png --style cubism --cubism-fragments 8 --cubism-angle-shift 15.0 --cubism-overlap 0.3 --cubism-seed 1

# abstract
ditto generate --input input.jpg --output out.png --style abstract --abstract-color-count 8 --abstract-shape-size 16 --abstract-simplify 0.5

# geometric
ditto generate --input input.jpg --output out.png --style geometric --geometric-shape-type polygon --geometric-shape-size 16 --geometric-seed 1

# kaleidoscope
ditto generate --input input.jpg --output out.png --style kaleidoscope --kaleidoscope-segments 8 --kaleidoscope-mirror-count 4 --kaleidoscope-rotation 0.0

# warp
ditto generate --input input.jpg --output out.png --style warp --warp-strength 50.0 --warp-frequency 0.1 --warp-wave-count 3 --warp-seed 1

# tessellation
ditto generate --input input.jpg --output out.png --style tessellation --tessellation-tile-count 12 --tessellation-tile-type hexagon --tessellation-rotation --tessellation-seed 1

# color_field
ditto generate --input input.jpg --output out.png --style color_field --color-field-color-count 8 --color-field-block-size 32 --color-field-noise 0.2 --color-field-seed 1

# impressionist
ditto generate --input input.jpg --output out.png --style impressionist --impressionist-brush-size 8 --impressionist-blur 2.0 --impressionist-color-vibrancy 1.3 --impressionist-stroke-density 0.6

# pointillism
ditto generate --input input.jpg --output out.png --style pointillism --pointillism-dot-size 3 --pointillism-dot-density 0.8 --pointillism-color-palette-size 64 --pointillism-seed 1

# watercolor
ditto generate --input input.jpg --output out.png --style watercolor --watercolor-bleed-amount 0.4 --watercolor-transparency 0.7 --watercolor-paper-texture 0.3 --watercolor-seed 1

# expressionist
ditto generate --input input.jpg --output out.png --style expressionist --expressionist-brush-width 6 --expressionist-color-intensity 1.5 --expressionist-stroke-length 12 --expressionist-edge-sharpness 0.7

# surrealist
ditto generate --input input.jpg --output out.png --style surrealist --surrealist-morph-factor 0.6 --surrealist-color-shift 0.3 --surrealist-blend-zones 8 --surrealist-seed 1

# pop_art
ditto generate --input input.jpg --output out.png --style pop_art --pop-art-color-count 4 --pop-art-halftone-dot-size 4 --pop-art-contrast 1.5 --pop-art-seed 1

# game_of_life
ditto generate --input input.jpg --output out.png --style game_of_life --game-of-life-generations 20 --game-of-life-density 0.3 --game-of-life-cell-size 4

# oil_painting
ditto generate --input input.jpg --output out.png --style oil_painting --oil-painting-brush-size 12 --oil-painting-intensity 0.8 --oil-painting-color-blend 0.6 --oil-painting-texture 0.4 --oil-painting-seed 1

# sketch
ditto generate --input input.jpg --output out.png --style sketch --sketch-pencil-size 2 --sketch-intensity 0.7 --sketch-shading 0.8 --sketch-detail 0.6 --sketch-seed 1

# cyberpunk
ditto generate --input input.jpg --output out.png --style cyberpunk --cyberpunk-neon-intensity 0.6 --cyberpunk-contrast 1.5 --cyberpunk-purple-tint 0.4 --cyberpunk-glow-size 4 --cyberpunk-scanline --cyberpunk-seed 1

Web API

cargo run -- serve --addr 0.0.0.0:8080
# POST /generate multipart form-data:
# - file: binary image (jpeg/png/webp)
# - style: string, e.g. "pixel", "impressionist", "watercolor", etc.
# - pixel_size: optional, integer for pixel style
# - levels: optional, integer for posterize
# - dither_levels: optional, integer for dither
# - edge_threshold: optional, integer for edge
# - mirror_tile: optional, integer for mirror
# - glitch_stride, glitch_max_shift, glitch_seed, channel_shift_px, channel_angle_deg, jitter_prob, jitter_max_shift, block_size, block_prob, block_shift_px: optional for glitch
# - cubism_fragments, cubism_angle_shift, cubism_overlap, cubism_seed: optional for cubism
# - abstract_color_count, abstract_shape_size, abstract_simplify: optional for abstract
# - geometric_shape_type, geometric_shape_size, geometric_seed: optional for geometric
# - kaleidoscope_segments, kaleidoscope_mirror_count, kaleidoscope_rotation: optional for kaleidoscope
# - warp_strength, warp_frequency, warp_wave_count, warp_seed: optional for warp
# - tessellation_tile_count, tessellation_tile_type, tessellation_rotation, tessellation_seed: optional for tessellation
# - color_field_color_count, color_field_block_size, color_field_noise, color_field_seed: optional for color_field
# - impressionist_brush_size, impressionist_blur, impressionist_color_vibrancy, impressionist_stroke_density: optional for impressionist
# - pointillism_dot_size, pointillism_dot_density, pointillism_color_palette_size, pointillism_seed: optional for pointillism
# - watercolor_bleed_amount, watercolor_transparency, watercolor_paper_texture, watercolor_seed: optional for watercolor
# - expressionist_brush_width, expressionist_color_intensity, expressionist_stroke_length, expressionist_edge_sharpness: optional for expressionist
# - surrealist_morph_factor, surrealist_color_shift, surrealist_blend_zones, surrealist_seed: optional for surrealist
# - pop_art_color_count, pop_art_halftone_dot_size, pop_art_contrast, pop_art_seed: optional for pop_art
# Input supports PNG/JPEG/WebP; output is PNG

Example request with curl:

curl -X POST "http://127.0.0.1:8080/generate" \
  -F "style=pixel" \
  -F "pixel_size=8" \
  -F "file=@input.png;type=image/png" \
  --output out.png

Yew example (frontend)

Run backend in one terminal:

cargo run -- serve --addr 127.0.0.1:8080

Run Yew client in another terminal (Trunk dev server):

rustup target add wasm32-unknown-unknown
cargo install trunk
cd examples/yew_client
trunk serve

Open the URL shown by Trunk (e.g., http://127.0.0.1:8081/). The Trunk proxy forwards POST /generate to http://127.0.0.1:8080/generate.

About

Generative art toolkit powered by nannou. Input an image, output a stylized image.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages