clojure2d.pixels
Operations on pixel levels.
Content
Namespace defines three main concepts:
- Pixels - channel values packed into array.
- Processors - parallel Pixels processing functions (like filters).
- Bins - log density renderer
Pixels
Pixels is type which represents image as int array divided into color channels. Layout is linear and interleaved which means that array is 1D and each pixel is represented by four consecutive values R, G, B, A. After first row goes second and so on.
Pixels allows mutation, you can read and set channel value or color:
- get-value, set-value - read or set channel value for given pixel and channel. Value should be within
[0-255]
range. - get-color, set-color - read or set color for given pixel. Returned color has Vec4 type.
- get-channel, set-channel - read or set whole channel as
ints
.
Pixel access can be made by (x,y)
coordinates or by index which is equivalent to (+ x (* y width))
.
Pixels implement ImageProto.
Creation / conversions
To create empty Pixels, call pixels.
You can also get and set Pixels from and to Images and Canvases or read from file.
Processors
Library supports several processing functions and helpers to parallely manipulate channels or colors. All functions are not destrictive, that means new object is created to store result of manipulation. Every processor accept one or more filtering functions which do the job. There are three main functions:
- filter-colors - to process colors. Uses function
f
which accepts color and should return color. Can be used to convert Pixels between different color spaces. - filter-channels - to process channel values. Uses function
f
which accepts channel number (values from 0 to 3), target Pixels and source Pixels and returns integer. You can provide different function for every channel. Can be used to apply filter (like blur). - blend-channels - to process pair of Pixels. Uses function
f
which accepts channel number, target and two Pixel values. compose-channels wrapper can be used to compose two Pixels using one of the blending functions defined in clojure2d.colors namespace.
Additionally other processing functions are prepared in case you want write own filters or converters:
- filter-colors-xy - process colors using function
f
which accepts Pixels and current position. - filter-channel - iterate through channel,
f
accepts channel value and returns new channel value - filter-channel-xy - iterate through channel,
f
accepts channel, Pixels and x,y position - blend-channels and blend-channel-xy - similar to two above,
f
accepts two Pixels instead of one.
Color space
To convert whole Pixels into different color space use filter-colors and pass one of the color space conversion functions defined under colorspaces*. Always use normalized version.
(filter-colors c/to-HSB* pixels-object)
Filters
There are several ready to use filters. All defined under filters-list variable. Some of the filters are creators and should be called with parametrization.
(filter-channels gaussian-blur-3 pixels-object)
(filter-channels (posterize 10) pixels-object)
Composing
To compose two Pixels use compose-channels and use name of composing function defined blends-list. Instead of name you can pass custom composing function.
(compose-channels :multiply pixels-1 pixels-2)
Log Density Rendering
Log Density Renderer was orginally created for fractal flames rendering and produces very smooth results. Details are described in this paper.
Renderer is point based (no other primitives) and supports selection of antialiasing (reconstruction) filters. Density estimation is not supported.
Rendering algorithm collects color channels values and counts number of hits for each pixel. For each pixel weighted average of all color values is calculated and log of number of hits gives alpha value. Pixel color is blended with background using alpha.
Rendering
First you have to create renderer with renderer function. By default no filter is used. In case you want to use filter call with: filter name as keyword (see below), optional: filter radius (default 2.0) and other filter parameters.
To set point call set-color.
Antialiasing filters
Below you have list of all available antialiasing filters. Each filter has radius and spread parameter.
- :gaussian
- :box - only radius
- :sinc - Windowed sinc filter
- :mitchell - Mitchell-Netravali filter, additional parameters: B and C (default: 1/3)
- :cubic
- :catmull
- :triangle
- :cosinebell
- :blackmann-harris
- :hann
- :none or
nil
- no filter
Converting
To convert renderer to Pixels just call to-pixels method with optional configuration. Configuration gives you possibility to control process of transformation to RGB data.
Configuration is a map with following fields:
- :background - color of the background (default: :black)
- :gamma-alpha - gamma correction for alpha
- :gamma-color - gamma correction for color, to adjust vibrancy
- :vibrancy: 0.0 - use calculated color 1.0 - use gamma corrected color (0.0-1.0) - mix between above
- :saturation - adjust saturation (0-2)
- :brightness - adjust brightness (0-2)
- :contrast - adjust contrast (0-2)
Parallel rendering
Construction of renderer enables parallel computing. Just create as many renderers as you want (you may use available-tasks value), run rendering in separate threads and then merge result with merge-renderers.
Categories
- Filters: blend-channel blend-channel-xy blend-channels box-blur box-blur-1 box-blur-2 box-blur-3 box-blur-5 brightness-contrast compose-channels composite dilate dilate-cross equalize erode erode-cross filter-channel filter-channel-xy filter-channels filter-colors filter-colors-xy gaussian-blur gaussian-blur-1 gaussian-blur-2 gaussian-blur-3 gaussian-blur-5 horizontal-blur horizontal-blur-1 horizontal-blur-2 horizontal-blur-3 horizontal-blur-5 median modulate negate normalize posterize posterize-16 posterize-4 posterize-8 quantile-1 quantile-2 quantile-3 quantile-5 quantile-6 quantile-7 solarize threshold threshold-25 threshold-50 threshold-75 tint vertical-blur vertical-blur-1 vertical-blur-2 vertical-blur-3 vertical-blur-5
- Log density renderer: add-pixel! get-color get-pixel gradient-renderer merge-gradient-renderers merge-renderers renderer set-color! to-pixels
- Pixels: *pixels-edge* clone-pixels get-channel get-color get-value load-pixels pixels set-canvas-pixels! set-channel! set-color! set-image-pixels! set-value! to-pixels
Other vars: ->GradientRenderer ->LDRenderer ->Pixels map->GradientRenderer map->LDRenderer set-renderer-scaling-factor!
Code snippets
Save pixels to image.
(defn saver
[f params & opts]
(let [n (str "images/pixels/" (first opts) ".jpg")]
(core/save (f) (str "docs/" n))
(str "../" n)))
*pixels-edge*
dynamic
If you access pixels which is outside possible range. You’ll always get some value. You can control what is returned by setting this variable. Possible values are:
:zero
- set0
:edge
- value from the edge of the image (left, right, top, bottom or corners) (default):wrap
- wrap around image- or channel value 0-255 - set specific value
Examples
Access pixels outside image range.
(binding [*pixels-edge* :zero] (get-color cockatoo -1 10))
;;=> [0.0 0.0 0.0 255.0]
(get-color cockatoo 0 10)
;;=> [54.0 94.0 155.0 255.0]
(binding [*pixels-edge* :edge] (get-color cockatoo -1 10))
;;=> [54.0 94.0 155.0 255.0]
(get-color cockatoo (- (core/width cockatoo) 100) 10)
;;=> [186.0 102.0 76.0 255.0]
(binding [*pixels-edge* :wrap] (get-color cockatoo -100 10))
;;=> [186.0 102.0 76.0 255.0]
(binding [*pixels-edge* 123] (get-color cockatoo -1 10))
;;=> [123.0 123.0 123.0 255.0]
Get values from second channel from outside image range.
(binding [*pixels-edge* :zero] (get-value cockatoo 1 -1 10))
;;=> 0
(get-value cockatoo 1 0 10)
;;=> 94
(binding [*pixels-edge* :edge] (get-value cockatoo 1 -1 10))
;;=> 94
(get-value cockatoo 1 (- (core/width cockatoo) 100) 10)
;;=> 102
(binding [*pixels-edge* :wrap] (get-value cockatoo 1 -100 10))
;;=> 102
(binding [*pixels-edge* 123] (get-value cockatoo 1 -1 10))
;;=> 123
blend-channel
(blend-channel f ch target p1 p2)
(blend-channel f)
Blend one channel, write result into target.
Blending function should two channel values and return new channel value.
This should be considered as helper function for blend-channels.
Examples
Create own blending function and apply to second channel of image and its blurred version.
(saver (fn []
(let [target (clone-pixels cockatoo)
wrong-avg (fn [v1 v2] (/ (+ v1 v2) 4.0))]
(blend-channel wrong-avg
1
target
cockatoo
(filter-channels box-blur-5 cockatoo))
target))
...)
blend-channel-xy
(blend-channel-xy f ch target p1 p2)
(blend-channel-xy f)
Blend one channel, write result into target.
Blending function should accept channel, two Pixels
and position x,y.
Examples
Create flip blender and apply to second channel.
(saver (fn []
(let [target (clone-pixels cockatoo)
flip-blend (fn [ch p1 p2 x y]
(let [v1 (get-value p1 ch y x)
v2 (get-value p2 ch x y)]
(/ (+ v1 v2) 2.0)))]
(blend-channel-xy flip-blend 1 target cockatoo cockatoo)
target))
...)
blend-channels
(blend-channels f0 f1 f2 f3 p1 p2)
(blend-channels f p1 p2)
(blend-channels f do-alpha? p1 p2)
Blend channels parallelly.
Similar to filter-channels
. Bleding function should accept: channel, target and two source pixels.
Examples
Create flip blender and apply to image.
(saver (fn []
(let [flip-blend (fn [ch p1 p2 x y]
(let [v1 (get-value p1 ch y x)
v2 (get-value p2 ch x y)]
(/ (+ v1 v2) 2.0)))]
(blend-channels (partial blend-channel-xy flip-blend)
cockatoo
cockatoo)))
...)
box-blur
(box-blur radius)
Create box blur for given radius.
Examples
Usage
(saver (fn [] (filter-channels (box-blur 20) cockatoo)) ...)
brightness-contrast
(brightness-contrast brightness contrast)
(brightness-contrast brightness)
Create brightness / contrast filter.
Values from 0-2.
Examples
Ligher
(saver (fn [] (filter-channels (brightness-contrast 1.5) cockatoo)) ...)
Darker
(saver (fn [] (filter-channels (brightness-contrast 0.5) cockatoo)) ...)
More contrast
(saver (fn [] (filter-channels (brightness-contrast 1.0 1.5) cockatoo))
...)
Less contrast
(saver (fn [] (filter-channels (brightness-contrast 1.0 0.5) cockatoo))
...)
clone-pixels
(clone-pixels p)
Clone Pixels, returns new object
Examples
Usage
(let [p1 (pixels 100 100)]
(set-color! p1 10 10 :maroon)
(get-color (clone-pixels p1) 10 10))
;;=> [128.0 0.0 0.0 255.0]
compose-channels
(compose-channels n1 n2 n3 n4 p1 p2)
(compose-channels n1 n2 n3 p1 p2)
(compose-channels n p1 p2)
(compose-channels n do-alpha? p1 p2)
Compose channels with blending functions.
You can give blending method name as keyword defined in blends-names. Or it can be blending function which accepts 2 doubles from 0.0 to 1.0 and returns double (0.0 - 1.0).
When there is no processing function for alpha, W3C alpha blending is applied.
Examples
Add two versions of the image
(saver
(fn []
(compose-channels :add cockatoo (filter-channels solarize cockatoo)))
...)
XOR two versions of the image
(saver
(fn []
(compose-channels :xor cockatoo (filter-channels solarize cockatoo)))
...)
Use different blending method for every channel.
(saver (fn []
(compose-channels :divide
:multiply
:mburn
cockatoo
(filter-channels solarize cockatoo)))
...)
Use custom function
(saver (fn []
(compose-channels (fn [v1 v2] (* v1 (- 1.0 v2)))
cockatoo
(filter-channels solarize cockatoo)))
...)
composite
(composite n)
Create java.awt.Composite object which can be used in set-composite.
Used to change default blending during drawing.
dilate
Dilate filter. See: dilate-cross.
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels dilate buff))
cockatoo
(range 5)))
...)
dilate-cross
Dilate using 5 pixels. See: dilate.
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels dilate-cross buff))
cockatoo
(range 5)))
...)
equalize
(equalize ch target p)
Equalize histogram.
Examples
Usage
(saver (fn [] (filter-channels equalize cockatoo)) ...)
erode
Erode filter. See: erode-cross.
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels erode buff))
cockatoo
(range 5)))
...)
erode-cross
Erode using 5 pixels. See: erode.
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels erode-cross buff))
cockatoo
(range 5)))
...)
filter-channel
(filter-channel f ch target p)
(filter-channel f)
Filter one channel, write result into target.
This is helper function to create own filters.
Function parameter is channel value and should return new value.
Examples
Operate on blue channel
(saver (fn []
(let [target (pixels 150 150)
filter (fn [v] (- 255 (/ v 2)))]
(filter-channel filter 2 target cockatoo)
target))
...)
filter-channel-xy
(filter-channel-xy f ch target p)
(filter-channel-xy f)
Filter one channel, write result into target.
This is helper function to create own filter.
Function parameters are: channel, pixels, x and y position.
Note: channel is first parameter.
Examples
Create filter and process channel.
(saver (fn []
(let [target (pixels 150 150)
filter (fn [ch p x y]
(let [v1 (get-value p ch (dec x) y)
v2 (get-value p ch (inc x) y)
v3 (get-value p ch x (dec y))
v4 (get-value p ch x (inc y))
avg (/ (+ v1 v2 v3 v4) 4.0)]
(if (< avg 128) 0 255)))]
(filter-channel-xy filter 0 target cockatoo)
(let [c0 (get-channel target 0)]
(set-channel! target 1 c0)
(set-channel! target 2 c0))
target))
...)
Create filter and process channel. Using filter-channels.
(saver
(fn []
(let [filter (filter-channel-xy (fn [ch p x y]
(let [v1 (get-value p ch (dec x) y)
v2 (get-value p ch (inc x) y)
v3 (get-value p ch x (dec y))
v4 (get-value p ch x (inc y))
avg (/ (+ v1 v2 v3 v4) 4.0)]
(if (< avg 128) 0 255))))
target (filter-channels filter nil nil nil cockatoo)]
(let [c0 (get-channel target 0)]
(set-channel! target 1 c0)
(set-channel! target 2 c0))
target))
...)
filter-channels
(filter-channels f0 f1 f2 f3 p)
(filter-channels f p)
(filter-channels f do-alpha? p)
Filter channels parallelly with filtering function. Build filtering function using filter-channel
or filter-channel-xy
helpers as with filter aplied partially. Filtering function parameters are: channel, target and source pixels.
When you pass one filter, three RGB channels will be processed (arity: 2). To enable alpha set do-alpha
parameter to true
(arity: 3). You can also use different filter for every channel separately (arity 5). Set nil
to skip particular channel.
Examples
Apply equalize filter for all channels
(saver (fn [] (filter-channels equalize cockatoo)) ...)
Apply 2 filters separately for 2 channels
(saver (fn [] (filter-channels negate (box-blur 10) nil nil cockatoo))
...)
Create gamma filter and use it to process channels
(saver
(fn []
(let [gamma-fn
(fn [amt v]
(let [vv (/ v 255.0) p (m/pow vv (/ amt))] (* p 255.0)))
my-gamma (partial gamma-fn 0.2)]
(filter-channels (partial filter-channel my-gamma) cockatoo)))
...)
filter-colors
(filter-colors f p)
Filter colors.
Filtering function should accept color and return color.
Examples
Convert to other colorspace.
(saver (fn [] (filter-colors c/to-LUV* cockatoo)) ...)
filter-colors-xy
(filter-colors-xy f p)
Filter colors.
Filtering function should accept Pixels, position as x,y values and return color
Examples
Shift image up.
(saver (fn []
(let [filter (fn [p x y] (get-color p x (+ y 75)))]
(binding [*pixels-edge* :wrap]
(filter-colors-xy filter cockatoo))))
...)
gaussian-blur
(gaussian-blur radius)
Create gaussian blur for given radius.
Examples
Usage
(saver (fn [] (filter-channels (gaussian-blur 20) cockatoo)) ...)
gaussian-blur-1
Examples
Usage
(saver (fn [] (filter-channels gaussian-blur-1 cockatoo)) ...)
gaussian-blur-2
Examples
Usage
(saver (fn [] (filter-channels gaussian-blur-2 cockatoo)) ...)
gaussian-blur-3
Examples
Usage
(saver (fn [] (filter-channels gaussian-blur-3 cockatoo)) ...)
gaussian-blur-5
Examples
Usage
(saver (fn [] (filter-channels gaussian-blur-5 cockatoo)) ...)
get-channel
(get-channel pixels ch)
Return whole ints
array with chosen channel
Examples
Extract one channel from Pixels.
(first (get-channel cockatoo 1))
;;=> 91
get-color
(get-color pixels x y)
(get-color pixels idx)
Get color by index or position. In case of low density rendering returns current average color without alpha value.
Examples
Get channel value from given position.
(get-color cockatoo 20 20)
;;=> [60.0 100.0 161.0 255.0]
(get-color cockatoo -10 -10)
;;=> [51.0 91.0 152.0 255.0]
(get-color cockatoo 20)
;;=> [52.0 92.0 153.0 255.0]
(get-color cockatoo 10000)
;;=> [56.0 66.0 39.0 255.0]
(get-color (core/canvas 100 100) 50 50)
;;=> [0.0 0.0 0.0 0.0]
(get-color (core/load-image "docs/cockatoo.jpg") 50 50)
;;=> [176.0 191.0 184.0 255.0]
Low density pixels color access.
(let [ldp (renderer 100 100)
v0 (get-color ldp 50 50)
v1 (get-color (set-color! ldp 50 50 :maroon) 50 50)]
{:before v0, :after v1})
;;=> {:after [128.0 0.0 0.0 255.0],
;;=> :before [##NaN ##NaN ##NaN 255.0]}
get-value
(get-value pixels ch x y)
(get-value pixels ch idx)
Get channel value by index or position.
Examples
Get channel value from given position.
(get-value cockatoo 1 20 20)
;;=> 100
(get-value cockatoo 3 20 20)
;;=> 255
(get-value cockatoo 0 -10 -10)
;;=> 51
(get-value cockatoo 1 20)
;;=> 92
(get-value cockatoo 3 20)
;;=> 255
(get-value cockatoo 0 10000)
;;=> 56
gradient-renderer
(gradient-renderer w h filter filter-radius & filter-params)
(gradient-renderer w h filter)
(gradient-renderer w h)
Create gradient renderer.
Optionally you can pass antialiasing filter and its parameters. Defaults to :none
.
Examples
Usage
(saver
(fn* []
(let [r (gradient-renderer 300 300)]
(dotimes [i 4000000]
(let [x (+ 150 (r/grand 30))
y (+ 150 (r/grand 30))
x (+ x
(* 20.0
(- (local-noise (/ x 50.0) (/ y 50.0) 0.34) 0.5)))
y (+ y
(* 20.0
(- (local-noise (/ y 50.0) (/ x 50.0) 2.23) 0.5)))]
(add-pixel! r x y)))
(to-pixels r)))
...)
Render with different gradient
(saver
(fn* []
(let [r (gradient-renderer 300 300)]
(dotimes [i 4000000]
(let [x (+ 150 (r/grand 30))
y (+ 150 (r/grand 30))
x (+ x
(* 20.0
(- (local-noise (/ x 50.0) (/ y 50.0) 0.34) 0.5)))
y (+ y
(* 20.0
(- (local-noise (/ y 50.0) (/ x 50.0) 2.23) 0.5)))]
(add-pixel! r x y)))
(to-pixels r {:gradient (c/gradient (c/palette :prl-10))})))
...)
Render with logarithmic scale
(saver
(fn* []
(let [r (gradient-renderer 300 300)]
(dotimes [i 4000000]
(let [x (+ 150 (r/grand 30))
y (+ 150 (r/grand 30))
x (+ x
(* 20.0
(- (local-noise (/ x 50.0) (/ y 50.0) 0.34) 0.5)))
y (+ y
(* 20.0
(- (local-noise (/ y 50.0) (/ x 50.0) 2.23) 0.5)))]
(add-pixel! r x y)))
(to-pixels r {:logarithmic? true})))
...)
horizontal-blur
(horizontal-blur radius)
Create horizontal blur for given radius.
Examples
Usage
(saver (fn [] (filter-channels (horizontal-blur 20) cockatoo)) ...)
horizontal-blur-1
Examples
Usage
(saver (fn [] (filter-channels horizontal-blur-1 cockatoo)) ...)
horizontal-blur-2
Examples
Usage
(saver (fn [] (filter-channels horizontal-blur-2 cockatoo)) ...)
horizontal-blur-3
Examples
Usage
(saver (fn [] (filter-channels horizontal-blur-3 cockatoo)) ...)
horizontal-blur-5
Examples
Usage
(saver (fn [] (filter-channels horizontal-blur-5 cockatoo)) ...)
load-pixels
(load-pixels n)
Load Pixels
from file.
Examples
Load file
(load-pixels "docs/cockatoo.jpg")
;;=> pixels (150, 150)
Usage
(saver (fn [] (load-pixels "docs/cockatoo.jpg")) ...)
median
Median filter
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels median buff))
cockatoo
(range 5)))
...)
merge-gradient-renderers
(merge-gradient-renderers target & renderers)
Merge gradient renderers and store result to the target.
Use this function to merge separate rendereing results (ex. from separeted threads).
This is mutating function. Data from list of renderers is added to the target.
merge-renderers
(merge-renderers target & renderers)
Paralelly merge renderers and store result to the target.
Use this function to merge separate rendereing results (ex. from separeted threads).
This is mutating function. Data from list of renderers is added to the target.
modulate
(modulate amt)
Examples
Saturate
(saver (fn []
(->> cockatoo
(filter-colors c/to-HSB*)
(filter-channels nil (modulate 2.0) nil nil)
(filter-colors c/from-HSB*)))
...)
Desaturate
(saver (fn []
(->> cockatoo
(filter-colors c/to-HCL*)
(filter-channels nil (modulate 0.2) nil nil)
(filter-colors c/from-HCL*)))
...)
Shift hue
(saver (fn []
(->> cockatoo
(filter-colors c/to-HCL*)
(filter-channels (modulate 0.2) nil nil nil)
(filter-colors c/from-HCL*)))
...)
normalize
(normalize ch target p)
Normalize channel values to full range.
Examples
Usage
(saver (fn [] (filter-channels normalize cockatoo)) ...)
pixels
(pixels a w h)
(pixels w h)
Create empty Pixels
object with w,h dimensions.
Optionally you can pass ints
array a
as a buffer. Size of array should be (* 4 w h)
.
Examples
Create pixels
(pixels 100 100)
;;=> pixels (100, 100)
Create pixels with given array
(pixels (int-array (* 10 10 4)) 10 10)
;;=> pixels (10, 10)
posterize
(posterize levels)
Create posterize filter for given radius.
Examples
Usage
(saver (fn [] (filter-channels (posterize 2) cockatoo)) ...)
quantile-1
Quantile (2/9) filter
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels quantile-1 buff))
cockatoo
(range 5)))
...)
quantile-2
Quantile (3/9) filter
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels quantile-2 buff))
cockatoo
(range 5)))
...)
quantile-3
Quantile (4/9) filter
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels quantile-3 buff))
cockatoo
(range 5)))
...)
quantile-5
Quantile (6/9) filter
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels quantile-5 buff))
cockatoo
(range 5)))
...)
quantile-6
Quantile (7/9) filter
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels quantile-6 buff))
cockatoo
(range 5)))
...)
quantile-7
Quantile (8/9) filter
Examples
Apply filter 5 times.
(saver (fn []
(reduce (fn [buff _] (filter-channels quantile-7 buff))
cockatoo
(range 5)))
...)
renderer
(renderer w h filter filter-radius & filter-params)
(renderer w h filter)
(renderer w h)
Create renderer.
Optionally you can pass antialiasing filter and its parameters. Defaults to :none
.
Examples
Log density rendering
(saver
(fn* []
(let [r (renderer 300 300)]
(dotimes [i 20000000]
(let [x (+ 150 (r/grand 30))
y (+ 150 (r/grand 30))
x (+ x
(* 20.0
(- (local-noise (/ x 50.0) (/ y 50.0) 0.34) 0.5)))
y (+ y
(* 20.0
(- (local-noise (/ y 50.0) (/ x 50.0) 2.23) 0.5)))]
(add-pixel! r x y :white)))
(to-pixels r {:gamma-alpha 0.6, :gamma-color 0.8})))
...)
Linear density rendering
(saver
(fn* []
(let [r (renderer 300 300)]
(dotimes [i 20000000]
(let [x (+ 150 (r/grand 30))
y (+ 150 (r/grand 30))
x (+ x
(* 20.0
(- (local-noise (/ x 50.0) (/ y 50.0) 0.34) 0.5)))
y (+ y
(* 20.0
(- (local-noise (/ y 50.0) (/ x 50.0) 2.23) 0.5)))]
(add-pixel! r x y :white)))
(to-pixels r {:gamma-alpha 0.6, :gamma-color 0.8, :linear? true})))
...)
Splat rendering
(saver
(fn* []
(let [r (renderer 300 300 :gaussian)]
(doseq [x (range 300)
y (range 300)]
(dotimes [i 10]
(let [xx (+ x (r/drand))
yy (+ y (r/drand))]
(add-pixel!
r
x
y
(c/gray (* 255.0 (local-noise (/ xx 50.0) (/ yy 50.0))))))))
(to-pixels r {:gamma-color 0.8, :splats? true})))
...)
Compare to native Java2d rendering. You can observe oversaturation.
(saver
(fn* []
(let [r (core/black-canvas 300 300)]
(core/with-canvas
[c r]
(core/set-color c :white 5)
(dotimes [i 2000000]
(let [x (+ 150 (r/grand 30))
y (+ 150 (r/grand 30))
x (+ x
(* 20.0
(- (local-noise (/ x 50.0) (/ y 50.0) 0.34) 0.5)))
y (+ y
(* 20.0
(- (local-noise (/ y 50.0) (/ x 50.0) 2.23)
0.5)))]
(core/point c x y))))
(to-pixels r)))
...)
set-canvas-pixels!
(set-canvas-pixels! canvas x y p)
(set-canvas-pixels! canvas p)
Set Pixels
to canvas. See set-image-pixels!.
Examples
Usage
(saver
(fn []
(let [i (core/canvas 100 100)
p2 (pixels 40 40)]
(core/with-canvas [c i]
(core/set-background c :maroon)
(to-pixels (set-canvas-pixels! c 25 15 p2)))))
...)
set-channel!
(set-channel! pixels ch v)
Set whole channel (as ints
array)
Examples
Copy channels
(get-color
(set-channel! (clone-pixels cockatoo) 0 (get-channel cockatoo 1))
20
20)
;;=> [100.0 100.0 161.0 255.0]
set-color!
(set-color! pixels x y v)
(set-color! pixels idx v)
Set color value by index or position
Examples
Set color in pixels
(let [p (pixels 100 100)
v0 (get-color p 50 50)
v1 (get-color (set-color! p 50 50 :maroon) 50 50)]
{:before v0, :after v1})
;;=> {:after [128.0 0.0 0.0 255.0], :before [0.0 0.0 0.0 0.0]}
Low density pixels color access.
(let [ldp (renderer 100 100)
v0 (get-color ldp 50 50)
v1 (get-color (set-color! ldp 50 50 :maroon) 50 50)]
{:before v0, :after v1})
;;=> {:after [128.0 0.0 0.0 255.0],
;;=> :before [##NaN ##NaN ##NaN 255.0]}
set-image-pixels!
(set-image-pixels! b x y pin)
(set-image-pixels! b p)
Set Pixels
to image, mutating it.
Optionally you can set position when Pixels object has smaller size.
Examples
Usage
(saver (fn []
(let [i (core/load-image "docs/cockatoo.jpg")
p2 (pixels 40 40)]
(to-pixels (set-image-pixels! i 25 15 p2))))
...)
set-renderer-scaling-factor!
(set-renderer-scaling-factor! renderer ch1-scale ch2-scale ch3-scale)
(set-renderer-scaling-factor! renderer scale)
Changes internal representation of density renderer values.
By default each channel is divided by 255.0 (and later multiplied by 255.0). Other values can be used to scale down and up other than RGB color ranges.
The main goal is to store values from 0.0
to 1.0
.
set-value!
(set-value! pixels ch x y v)
(set-value! pixels ch idx v)
Set channel value by index or position
Examples
Set value in pixels
(let [p (pixels 100 100)
v0 (get-value p 1 50 50)
v1 (get-value (set-value! p 50 50 111) 50 50)]
{:before v0, :after v1})
;;=> {:after 111, :before 0}
solarize
(solarize ch target p)
Solarize filter.
Examples
Usage
(saver (fn [] (filter-channels solarize cockatoo)) ...)
threshold
(threshold amount)
(threshold amount-low amount-high)
Create threshold filter.
You can pass amount
from 0-1. or range.
Note if you want b&w result first convert to gray color.
Examples
Usage
(saver (fn [] (filter-channels (threshold 0.9) cockatoo)) ...)
Usage (two parameters)
(saver (fn [] (filter-channels (threshold 0.6 0.9) cockatoo)) ...)
Usage on b&w
(saver (fn []
(filter-channels (threshold 0.4)
(filter-colors c/to-Gray* cockatoo)))
...)
tint
(tint col)
(tint col-low col-high)
(tint col-low col-mid col-high)
Create tinting filter.
- one color - tint
- two colors - interpolate between
col-low
for black andcol-high
for white. - three colors - like above but uses also
mid-color
for mid tones.
Examples
Usage
(saver (fn [] (filter-channels (tint :hotpink) cockatoo)) ...)
Usage
(saver (fn [] (filter-channels (tint :indigo :lightblue) cockatoo)) ...)
Usage
(saver (fn []
(filter-channels (tint :gray :lightblue :maroon) cockatoo))
...)
to-pixels
(to-pixels pixels)
(to-pixels pixels x y w h)
(to-pixels pixels cfg)
Convert to Pixels. For low density rendering provide configuration. Works with Image/Canvas/Window and low density renderer.
Examples
Convert various types to pixels
(to-pixels (pixels 100 100))
;;=> pixels (100, 100)
(to-pixels (core/load-image "docs/cockatoo.jpg"))
;;=> pixels (150, 150)
(to-pixels (core/canvas 50 50))
;;=> pixels (50, 50)
(to-pixels (renderer 10 10))
;;=> pixels (10, 10)
vertical-blur
(vertical-blur radius)
Create vertical blur for given radius.
Examples
Usage
(saver (fn [] (filter-channels (vertical-blur 20) cockatoo)) ...)
vertical-blur-1
Examples
Usage
(saver (fn [] (filter-channels vertical-blur-1 cockatoo)) ...)
vertical-blur-2
Examples
Usage
(saver (fn [] (filter-channels vertical-blur-2 cockatoo)) ...)
vertical-blur-3
Examples
Usage
(saver (fn [] (filter-channels vertical-blur-3 cockatoo)) ...)
vertical-blur-5
Examples
Usage
(saver (fn [] (filter-channels vertical-blur-5 cockatoo)) ...)