Home

Awesome

vpype flow imager

<img src="https://github.com/serycjon/vpype-flow-imager/blob/master/examples/coffee.jpg?raw=true" width="300" /> <img src="https://github.com/serycjon/vpype-flow-imager/blob/master/examples/coffee_out.png?raw=true" width="300" />

vpype plug-in to convert images to flow field line art inspired by Sean M. Puckett's work and the "Creating evenly-spaced streamlines of arbitrary density" paper by Jobard and Lefer.

Getting Started

For an existing vpype installation using pipx, use the following command:

$ pipx inject vpype 'git+https://github.com/serycjon/vpype-flow-imager.git#egg=vpype-flow-imager[all]'

For an existing vpype installation using pip in a virtual environment, activate the virtual environment and using the following command:

$ pip install 'git+https://github.com/serycjon/vpype-flow-imager.git#egg=vpype-flow-imager[all]'

For a new installation of vpype flow imager, use the following commands:

$ python3.8 -m venv my_virtual_env
$ source my_virtual_env/bin/activate
$ pip install 'git+https://github.com/serycjon/vpype-flow-imager.git#egg=vpype-flow-imager[all]'

vpype is automatically installed with vpype flow imager, so no further steps are required.

You can confirm that the installation was successful with the following command, which also happens to tell you all you need to know to use vpype flow imager:

$ vpype flow_img --help
Usage: vpype flow_img [OPTIONS] FILENAME

  Generate flowline representation from an image.

  The generated flowlines are in the coordinates of the input image, resized
  to have dimensions at most `--max_size` pixels.

Options:
  -fi, --flow_image FILE          An image to use for the flow field. X and Y
                                  components of the flow vector are encoded
                                  in the red and green channels, as in a
                                  normal map. Must be the same size as the
                                  main input image. It might work if they
                                  have exactly the same aspect ratio.
  -nc, --noise_coeff FLOAT        Simplex noise coordinate multiplier. The
                                  smaller, the smoother the flow field.
                                  [default: 0.001]
  -nf, --n_fields INTEGER         Number of rotated copies of the flow field
                                  [default: 1]
  -ms, --min_sep LENGTH           Minimum flowline separation  [default: 0.8]
  -Ms, --max_sep LENGTH           Maximum flowline separation  [default: 10]
  -ml, --min_length LENGTH        Minimum flowline length  [default: 0]
  -Ml, --max_length LENGTH        Maximum flowline length  [default: 40]
  --max_size LENGTH               The input image will be rescaled to have
                                  sides at most max_size px  [default: 800]
  -ef, --search_ef INTEGER        HNSWlib search ef (higher -> more accurate,
                                  but slower)  [default: 50]
  -s, --seed INTEGER              PRNG seed (overriding vpype seed)
  -fs, --flow_seed INTEGER        Flow field PRNG seed (overriding the main
                                  `--seed`)
  -tf, --test_frequency FLOAT     Number of separation tests per current
                                  flowline separation  [default: 2]
  -f, --field_type [noise|curl_noise]
                                  flow field type [default: noise]
  --transparent_val INTEGER RANGE
                                  Value to replace transparent pixels
                                  [default: 127; 0<=x<=255]
  -tm, --transparent_mask         Remove lines from transparent parts of the
                                  source image.  [default: False]
  -efm, --edge_field_multiplier FLOAT
                                  flow along image edges
  -dfm, --dark_field_multiplier FLOAT
                                  flow swirling around dark image areas
  -kdt, --kdtree_searcher         Use exact nearest neighbor search with
                                  kdtree (slower, but more precise)  [default:
                                  False]
  --cmyk                          Split image to CMYK and process each channel
                                  separately.  The results are in
                                  consecutively numbered layers, starting from
                                  `layer`.  [default: False]
  --rotate DEGREES                rotate the flow field  [default: 0]
  -l, --layer LAYER               Target layer or 'new'.  When CMYK enabled,
                                  this indicates the first (cyan) layer.
  --help                          Show this message and exit.  [default:
                                  False]

You will need a C++ compiler before running the default flow imager installation. One way of getting the compiler on Windows is installing Visual Studio with C++ package (tutorial). If the installation fails on some things related to "hnswlib", you can use the fallback installation, removing the [all] from the installation command, e.g.:

$ pipx inject vpype git+https://github.com/serycjon/vpype-flow-imager

If you still get errors, feel free to create an issue here on github, or ask around at the (drawingbots discord).

To create a SVG, combine the flow_img command with the write command (check vpype's documentation for more information). Here is an example:

$ vpype flow_img input.jpg write output.svg

Examples

The example output was generated with:

$ cd examples
$ vpype flow_img -nf 6 coffee.jpg write coffee_out.svg show

It took around 3 minutes on my laptop. In this example, the flow field was rotated 6 times to get hexagonal structure in the result.

The default:

$ vpype flow_img coffee.jpg write coffee_out.svg show

produces a smoother result like:

<img src="https://github.com/serycjon/vpype-flow-imager/blob/master/examples/coffee_single.png?raw=true" width="300" />

You can control the result line density by changing the --min_sep and --max_sep parameters.

You can also locally override the vpype PRNG seed using the --seed and --flow_seed parameters. The --flow_seed is used only in the flow field construction, so if you want to create a multi-layer svg (e.g. CMYK), you can do something like

vpype flow_img -fs 42 -l 1 C.jpg flow_img -fs 42 -l 2 M.jpg flow_img -fs 42 -l 3 Y.jpg flow_img -fs 42 -l 4 K.jpg write --layer-label "Pen%d" cmyk.svg show

By specifying the same -fs (--flow_seed) for all the layers, you will get the same flowline directions on all the layers.

The following is an example with curl_noise and dark_field enabled:

vpype -v -s 42 flow_img -f curl_noise -dfm 1 -nc 0.03 examples/coffee.jpg write examples/coffee_dark.svg
<img src="https://github.com/serycjon/vpype-flow-imager/blob/master/examples/coffee_dark.png?raw=true" width="300" />

Parameters

Starting from the most interesting / useful:

(feel free to create a pull request with better documentation)

License

GNU GPLv3. See the LICENSE file for details. Example coffee photo by jannoon028 Kd-tree searcher CC0 from Python-KD-Tree.