clojure2d.extra.glitch
Various glitching pixel filters or functions
Filter
Use following filters with filter-channels function.
- Slitscan - x/y slitscan simulation based on wave functions
- Shift-channels - just shift channels
- Mirror - mirror image along different axes
- Slitscan2 - slitscan simulation based on vector fields
- Fold - apply vector field on the image
- Pix2line - convert pixel into horizontal line
Machines
Short sketches operating on images/pixels.
- Blend - compose two images in glitchy way
All filters are equiped with random configuration generator.
Categories
Other vars: blend-machine blend-machine-random-config fold fold-random-config imgslicer mirror mirror-random-config mirror-types pix2line pix2line-random-config shift-channels shift-channels-random-config slitscan slitscan-random-config slitscan2 slitscan2-random-config
Code snippets
Save glitch
(defn save-result
[f params & opts]
(let [n (str "images/glitch/" (first opts) ".jpg")]
(save f (str "docs/" n))
(str "../" n)))
blend-machine
(blend-machine p1 p2)
(blend-machine {:keys [switch? in1-cs in2-cs out-cs in1-to? in2-to? out-to? blend-ch1 blend-ch2 blend-ch3]} p1 p2)
Blend two Pixels
based on configuration.
The idea is to compose channels separately in different color spaces.
Full flow does following steps:
- convert inputs to (or from) selected color spaces
- compose each channel separately using different method
- convert output to (or from) selected color space
Parametrization:
:switch?
- reverse input order:in1-cs
- color space for first image:in2-cs
- color space for second image:out-cs
- color space for output:in1-to?
,:in2-to?
,:cs-to?
- which conversion to select: to color space or from color space:blend-ch1
,:blend-ch2
,:blend-ch3
- blend methods for each channel
Examples
Usage
(save-result (let [blend-conf {:blend-ch3 :hardmix,
:out-cs :Cubehelix,
:blend-ch2 :mlinearburn,
:switch? true,
:out-to? true,
:in1-cs :LUV,
:in1-to? true,
:in2-cs :XYZ,
:blend-ch1 :mdodge,
:in2-to? true}
p2l-conf {:nx 9,
:ny 3,
:scale 4.2,
:tolerance 37,
:nseed -1,
:whole true,
:shiftx 0.66,
:shifty 0.46}
p2 (p/filter-channels (pix2line p2l-conf) samurai)]
(blend-machine blend-conf samurai p2))
...)

blend-machine-random-config
(blend-machine-random-config)
Random configuration for blend machine.
Examples
Usage
(blend-machine-random-config)
;;=> {:blend-ch1 :average,
;;=> :blend-ch2 :overlay,
;;=> :blend-ch3 nil,
;;=> :in1-cs :YCgCo,
;;=> :in1-to? false,
;;=> :in2-cs :YCgCo,
;;=> :in2-to? false,
;;=> :out-cs :YCgCo,
;;=> :out-to? true,
;;=> :switch? false}
fold
(fold {:keys [fields r]})
(fold)
Folding filter based on vector fields.
Parameters:
:fields
- vector fields configuration combine:r
- range value 1.0-3.0
Examples
Fold with random config
(save-result (p/filter-channels (fold) samurai) ...)

Provided config
(save-result
(let [conf
{:fields
{:type :operation,
:name :comp,
:var1 {:type :variation,
:name :pressure-wave,
:amount 1.0,
:config {:x-freq -0.27, :y-freq 5.92}},
:var2
{:type :variation, :name :besselj, :amount 1.0, :config {}},
:amount 1.0},
:r 4.0}]
(p/filter-channels (fold conf) samurai))
...)

Provided config with different range value for each channel
(save-result
(let [conf
{:fields {:type :operation,
:name :comp,
:var1 {:type :variation,
:name :perlin2,
:amount 1.0,
:config {:seed 112, :scale -1.13, :octaves 4}},
:var2 {:type :variation,
:name :exponential,
:amount 1.0,
:config {}},
:amount 1.0},
:r 2.0}]
(p/filter-channels (fold (assoc conf :r 1.9))
(fold (assoc conf :r 2.0))
(fold (assoc conf :r 2.1))
nil
samurai))
...)

fold-random-config
Generate random configuration for vector fields slitscan.
r
- field range (default 2.0)d
- fields configuration depth (default up to 3)
Examples
Usage
(fold-random-config)
;;=> {:fields {:amount 1.0,
;;=> :name :comp,
;;=> :type :operation,
;;=> :var1 {:amount 1.0,
;;=> :name :deriv,
;;=> :step 0.11232961633962182,
;;=> :type :operation,
;;=> :var {:amount 1.0,
;;=> :config {:dampx 1.0958284032985843,
;;=> :dampy -1.3387110728673306,
;;=> :freqx 0.1813757206782365,
;;=> :freqy 5.902751595793957,
;;=> :scalex -1.3550486340083079,
;;=> :scaley 1.4294196038977156,
;;=> :use-cos-x true,
;;=> :use-cos-y true},
;;=> :name :waves2wf,
;;=> :type :variation}},
;;=> :var2 {:amount 1.0,
;;=> :config {:k 0.007739299591828619},
;;=> :name :jacdn,
;;=> :type :variation}},
;;=> :r 2.0}
(fold-random-config 3.1234)
;;=> {:fields
;;=> {:amount 1.1182459950165564,
;;=> :name :mult,
;;=> :type :operation,
;;=> :var1 {:amount -1.914772318076563,
;;=> :name :comp,
;;=> :type :operation,
;;=> :var1 {:amount 1.0,
;;=> :name :add,
;;=> :type :operation,
;;=> :var1 {:amount 1.2959200276290375,
;;=> :config {:line-up -0.006473361294915936,
;;=> :pull -0.2765606750745764,
;;=> :rotate 0.8306427900554345,
;;=> :x 0.5432075779973433,
;;=> :y -0.7652347723828974},
;;=> :name :kaleidoscope,
;;=> :type :variation},
;;=> :var2 {:amount -1.2281130718469542,
;;=> :config {:a 0.78987372525014,
;;=> :b 1.271819593617363,
;;=> :c 2.3509537522799593,
;;=> :d 0.743066030621359,
;;=> :inside false,
;;=> :shape 3},
;;=> :name :hole2,
;;=> :type :variation}},
;;=> :var2 {:amount 1.0,
;;=> :config {:space 0.97444061400831,
;;=> :spin -1.264520002241417,
;;=> :twist -2.6510912787124057,
;;=> :x -0.3627663939623622,
;;=> :y 0.10296978192540829},
;;=> :name :lazysusan,
;;=> :type :variation}},
;;=> :var2 {:amount -0.467030784652247,
;;=> :config {},
;;=> :name :cosh,
;;=> :type :variation}},
;;=> :r 3.1234}
(fold-random-config 3.1234 0)
;;=> {:fields {:amount 1.0,
;;=> :config {:amplitude 1.8809884039532814,
;;=> :damping 0.9780798816320889,
;;=> :frequency -1.2851861364858639,
;;=> :separation 2.4139742288051402},
;;=> :name :oscilloscope,
;;=> :type :variation},
;;=> :r 3.1234}
imgslicer
(imgslicer pixels {:keys [distance threshold min-size mode], :or {distance v/dist, threshold 200, min-size 500, mode :color}, :as options})
mirror
(mirror t)
(mirror)
Mirror image for given (or random) mirroring functions.
Examples
Random mirror
(save-result (p/filter-channels (mirror) samurai) ...)

Mirror R(ight) to left
(save-result (p/filter-channels (mirror :R) samurai) ...)

Mirror each channel separately
(save-result
(p/filter-channels (mirror :L) (mirror :R) (mirror :U) nil samurai)
...)

mirror-random-config
(mirror-random-config)
Generate random mirroring functions.
Examples
Usage
(mirror-random-config)
;;=> :SUL2
(mirror-random-config)
;;=> :SDR2
(mirror-random-config)
;;=> :R
mirror-types
Map of names and mirroring functions
Examples
List of mirror function keys
(sort (keys mirror-types))
;;=> (:D :DL
;;=> :DL2 :DR
;;=> :DR2 :L
;;=> :R :RDL
;;=> :RDR :RUL
;;=> :RUR :SDL
;;=> :SDL2 :SDR
;;=> :SDR2 :SUL
;;=> :SUL2 :SUR
;;=> :SUR2 :U
;;=> :UL :UL2
;;=> :UR :UR2)
pix2line
(pix2line)
(pix2line {:keys [tolerance whole], :as config})
Pix2line effect. Convert pixels to lines.
Parametrization:
:nx
,:ny
- grid size:scale
- grid scaling factor:tolerance
- factor which regulates when start new line:nseed
- noise seed:whole
- skip lines or not:shiftx
,:shifty
- noise shift
Examples
Random pix2line
(save-result (p/filter-channels (pix2line) samurai) ...)

With configuration, slightly modified for each channel
(save-result
(let [conf {:nx 9,
:ny 3,
:scale 4.2,
:tolerance 37,
:nseed -1,
:whole true,
:shiftx 0.66,
:shifty 0.46}]
(p/filter-channels (pix2line conf)
(pix2line (assoc conf :scale 1))
(pix2line (assoc conf :scale 10 :tolerance 100))
nil
samurai))
...)

pix2line-random-config
(pix2line-random-config)
Make random config for pix2line.
Examples
Usage
(pix2line-random-config)
;;=> {:nseed -104559432,
;;=> :nx 19,
;;=> :ny 27,
;;=> :scale 4.827626098091167,
;;=> :shiftx 0.16595269492440257,
;;=> :shifty 0.8787030351906517,
;;=> :tolerance 17,
;;=> :whole true}
shift-channels
(shift-channels)
(shift-channels {:keys [x-shift y-shift], :or {x-shift 0.05, y-shift -0.05}})
Shift channels by given amount.
Parameters:
:x-shift
- shift amount along x axis:y-shift
- shift amount along y axis
Examples
Shift red and blue channels
(save-result
(p/filter-channels (shift-channels) nil (shift-channels) nil samurai)
...)

Shift hue and saturation channels
(save-result (let [filt (shift-channels {:x-shift -0.2, :y-shift 1.0})]
(->> samurai
(p/filter-colors c/to-HSV*)
(p/filter-channels filt filt nil nil)
(p/filter-colors c/from-HSV*)))
...)

shift-channels-random-config
(shift-channels-random-config)
(shift-channels-random-config spread)
Random shift values along x and y axes.
Optionally provide spread
parameter to define maximum shift value.
Examples
Usage
(shift-channels-random-config)
;;=> {:x-shift -0.04967620943383977, :y-shift -0.07077799115763057}
(shift-channels-random-config 100)
;;=> {:x-shift 52.49427712553219, :y-shift 55.42003937187266}
slitscan
(slitscan)
(slitscan {:keys [x y], :or {x [(make-random-wave)], y [(make-random-wave)]}})
Create slitscan filter funtion.
Config is a map each axis has it’s own list of maps defining waves. Each map contains:
:wave
- oscillator name (see oscillators.:freq
- wave frequency:amp
- wave amplitude:phase
- wave phase (0-1).
Examples
Random slitscan
(save-result (p/filter-channels (slitscan) samurai) ...)

Slitscan with parameters
(save-result
(p/filter-channels
(slitscan {:x [{:wave :triangle, :freq 4, :amp 0.25, :phase 0.8}],
:y [{:wave :sin, :freq 2, :amp 0.5, :phase 0.5}]})
samurai)
...)

slitscan-random-config
(slitscan-random-config nx ny)
(slitscan-random-config)
Create list of random waves for each axis separately.
Optionally you can pass number of waves to create for each axis.
Examples
Usage
(slitscan-random-config)
;;=> {:x ({:amp 0.5, :freq 2, :phase 0.6994181810424116, :wave :square}
;;=> {:amp 0.0625, :freq 16, :phase 0.9024742808325945, :wave :saw}
;;=> {:amp 1.0, :freq 1, :phase 0.6694941331632842, :wave :triangle}
;;=> {:amp 0.125,
;;=> :freq 8,
;;=> :phase 0.9509626955363083,
;;=> :wave :cut-triangle}),
;;=> :y ({:amp 0.125, :freq 8, :phase 0.7944420120329878, :wave :square}
;;=> {:amp 0.125, :freq 8, :phase 0.41133168837663625, :wave :noise})}
(slitscan-random-config 1 1)
;;=> {:x ({:amp 0.03125, :freq 32, :phase 0.24098886071591363, :wave :sin}),
;;=> :y ({:amp 0.015625, :freq 64, :phase 0.46036836977931017, :wave :saw})}
slitscan2
(slitscan2 {:keys [fields r], :or {r 2.0, fields (var/random-configuration 0)}})
(slitscan2)
Slitscan filter based on vector fields.
Parameters:
:fields
- vector fields configuration combine:r
- range value 1.0-3.0
Examples
Slitscan with random config
(save-result (p/filter-channels (slitscan2) samurai) ...)

Provided config
(save-result
(let [conf
{:fields
{:type :operation,
:name :comp,
:var1 {:type :variation,
:name :pressure-wave,
:amount 1.0,
:config {:x-freq -0.27, :y-freq 5.92}},
:var2
{:type :variation, :name :besselj, :amount 1.0, :config {}},
:amount 1.0},
:r 4.0}]
(p/filter-channels (slitscan2 conf) samurai))
...)

Provided config with different range value for each channel
(save-result
(let [conf
{:fields {:type :operation,
:name :comp,
:var1 {:type :variation,
:name :perlin2,
:amount 1.0,
:config {:seed 112, :scale -1.13, :octaves 4}},
:var2 {:type :variation,
:name :exponential,
:amount 1.0,
:config {}},
:amount 1.0},
:r 2.0}]
(p/filter-channels (slitscan2 (assoc conf :r 1.9))
(slitscan2 (assoc conf :r 2.0))
(slitscan2 (assoc conf :r 2.1))
nil
samurai))
...)

slitscan2-random-config
(slitscan2-random-config)
(slitscan2-random-config r)
(slitscan2-random-config r d)
Generate random configuration for vector fields slitscan.
r
- field range (default 2.0)d
- fields configuration depth (default up to 3)
Examples
Usage
(slitscan2-random-config)
;;=> {:fields {:amount 1.0,
;;=> :name :comp,
;;=> :type :operation,
;;=> :var1 {:amount 1.0,
;;=> :name :mult,
;;=> :type :operation,
;;=> :var1 {:amount 0.5952954185041754,
;;=> :config {},
;;=> :name :squarize,
;;=> :type :variation},
;;=> :var2 {:amount -0.8315860454290425,
;;=> :config {:amp 0.21182147687145636,
;;=> :amp2 -0.5931344545311442,
;;=> :angle 5.721584534486101,
;;=> :angle2 3.947251211103117,
;;=> :dir 4.835502337957393,
;;=> :dir2 5.650061538138282,
;;=> :freq 1.4681709558484077,
;;=> :freq2 -0.934449890986747,
;;=> :phase 0.12918759463094132,
;;=> :phase2 0.15256230289499584},
;;=> :name :vibration,
;;=> :type :variation}},
;;=> :var2
;;=> {:amount 1.0, :config {}, :name :flipy, :type :variation}},
;;=> :r 2.0}
(slitscan2-random-config 3.1234)
;;=> {:fields
;;=> {:amount 0.359409194634897,
;;=> :name :add,
;;=> :type :operation,
;;=> :var1 {:amount -1.086502194582573,
;;=> :name :comp,
;;=> :type :operation,
;;=> :var1
;;=> {:amount 1.0,
;;=> :name :angles,
;;=> :type :operation,
;;=> :var1 {:amount 1.0,
;;=> :config {:space -0.42914621055226654,
;;=> :spin-in -1.600562704525317,
;;=> :spin-out 2.3425379156980783},
;;=> :name :lazytravis,
;;=> :type :variation},
;;=> :var2
;;=> {:amount 1.0, :config {}, :name :spiral, :type :variation}},
;;=> :var2 {:amount 1.0,
;;=> :config {},
;;=> :name :ellipticprecision,
;;=> :type :variation}},
;;=> :var2 {:amount -1.6958417602398463,
;;=> :config {:amplitude -1.8110183721848179,
;;=> :damping 0.0,
;;=> :frequency-x -7.701623885661218,
;;=> :frequency-y 9.072315283735847,
;;=> :perturbation 0.27333349093431647,
;;=> :separation 2.392418269408841},
;;=> :name :oscilloscope2,
;;=> :type :variation}},
;;=> :r 3.1234}
(slitscan2-random-config 3.1234 0)
;;=> {:fields {:amount 1.0,
;;=> :config {:effect 0.6092573125119074},
;;=> :name :funnel,
;;=> :type :variation},
;;=> :r 3.1234}