(with-open [image (v/from-file "dev/rabbit.jpg" {:shrink 2})]
(v/metadata image)
(v/shape image)
(v/write-to-file image "rabbit.png" {:compression 9})
(v/write-to-buffer image ".png" {:compression 9}))
The snippets below show the main API shapes inline. For runnable
end-to-end scripts, see the examples in examples/:
examples/create_thumbnail.clj creates a thumbnail from a local file and writes it back out.
examples/chain_transforms.clj chains several image operations together with the threading style API.
examples/compose_images.clj joins two images and builds a small grid with join and arrayjoin.
examples/bytes_and_streams.clj reads image bytes into memory, streams them through libvips, and writes the result back out.
examples/http_stream_fetch.clj streams an HTTP response body into libvips and saves a transformed result.
examples/image_diff.clj compares two same-sized images, thresholds the absolute difference, and composites a red highlight overlay onto the changed pixels.
examples/palette_extractor.clj extracts the top dominant colors from an image with hist_find_ndim, prints channel stats from stats, and renders a swatch strip below the source image.
examples/metadata_roundtrip.clj reads and writes metadata fields before saving an image.
examples/animated_gif.clj loads every GIF frame, transforms each page, and writes an animated result.
Use the file helpers when your source and destination already live on disk and you want libvips to infer formats from the path or suffix.
(with-open [image (v/from-file "dev/rabbit.jpg" {:shrink 2})]
(v/metadata image)
(v/shape image)
(v/write-to-file image "rabbit.png" {:compression 9})
(v/write-to-buffer image ".png" {:compression 9}))
ol.vips exposes a curated v/metadata summary and a generic header
API for libvips metadata fields.
(with-open [image (v/from-file "dev/rabbit.jpg")]
{:meta (v/metadata image)
:width (v/field image "width")
:fields (take 5 (v/field-names image))})
;; => {:meta {:width 2490, :height 3084, :bands 3, :has-alpha? false}
;; :width 2490
;; :fields ("width" "height" "bands" "format" "coding")}
Immutable metadata edits use assoc/update/dissoc style names.
(with-open [image (v/from-file "dev/rabbit.jpg")
tagged (-> image
(v/assoc-field "xres" 10.0)
(v/update-field "yres" (constantly 10.0)))]
(v/write-to-file tagged "rabbit-copy.jpg" {:strip false})
(select-keys (v/headers tagged) ["width" "height" "xres" "yres"]))
Load every page or frame with a format-specific loader and
{:n -1}. libvips represents animated and multipage images as one
tall strip plus metadata such as n-pages, page-height, loop, and
delay.
(require '[ol.vips :as v]
'[ol.vips.operations :as ops])
(with-open [image (ops/gifload "test/fixtures/cogs.gif" {:n -1})
cropped (v/extract-area-pages image 10 7 50 50)
turned (v/rot-pages cropped :d90)
looped (v/assoc-loop-count turned 2)]
(v/write-to-file looped "cogs-turned.gif")
(v/metadata looped))
;; => {:width 50, :height 250, :bands 4, :has-alpha? true, :pages 5, ...}
The dedicated animated helpers are:
v/pages, v/page-height, v/page-delays, and v/loop-count
v/assoc-pages, v/assoc-page-height, v/assoc-page-delays, and
v/assoc-loop-count
v/extract-area-pages, v/embed-pages, v/rot-pages, and
v/assemble-pages
These helpers work best for uniform-height multipage inputs such as animated GIF/WebP strips and similarly-shaped TIFF/PDF inputs.
For a deeper guide, see Multipage and Animated Images.
The generic loaders v/from-file, v/from-buffer, and v/from-stream
auto-detect the input format and accept option maps that libvips
forwards to the selected loader. When you need format-specific behavior,
use the generated loader operations in ol.vips.operations, such as
ops/jpegload.
ol.vips blocks libvips operations marked as untrusted by default. This can
block loaders with a larger attack surface, such as PDF or ImageMagick-backed
formats.
If you trust your input and need those operations, opt in explicitly before loading that data:
(require '[ol.vips :as v]
'[ol.vips.operations :as ops])
(v/set-block-untrusted-operations! false)
(with-open [image (ops/pdfload "document.pdf")]
(v/metadata image))
Use that override only for trusted inputs. See the upstream
vips_block_untrusted_set
documentation. In libvips terms this is equivalent to calling
vips_block_untrusted_set(FALSE) after initialization.
JPEG auto-rotation rotates the image according to its EXIF orientation at load time:
(require '[ol.vips :as v]
'[ol.vips.operations :as ops])
(with-open [image (ops/jpegload "dev/rabbit.jpg" {:autorotate true})]
(v/write-to-file image "rabbit-upright.jpg")
(v/metadata image))
from-stream reads from any java.io.InputStream. from-buffer reads
from a byte array already in memory.
(require '[babashka.http-client :as http]
'[ol.vips :as v]
'[ol.vips.operations :as ops])
(import '[java.io FileOutputStream])
(with-open [response-body (:body (http/get "https://casey.link/square-flask.png"
{:as :stream}))
image (v/from-stream response-body {:access :sequential
:fail-on :error})
thumbnail (ops/thumbnail-image image 200)
out (FileOutputStream. "square-flask-thumb.png")]
(v/write-to-stream thumbnail out ".png")
(v/metadata thumbnail))
write-to-stream writes encoded bytes to any java.io.OutputStream.
(require '[babashka.fs :as fs]
'[ol.vips :as v]
'[ol.vips.operations :as ops])
(import '[java.io FileOutputStream])
(let [source-bytes (fs/read-all-bytes "dev/rabbit.jpg")]
(with-open [image (v/from-buffer source-bytes)
thumbnail (ops/thumbnail-image image 200)
out (FileOutputStream. "rabbit-thumb.png")]
(v/write-to-stream thumbnail out ".png")
(v/metadata thumbnail)))
autorot returns a closeable result map. You can inspect :angle and
:flip, and still use the same value anywhere an image is expected.
(with-open [image (v/from-file "dev/rabbit.jpg")
autorot (ops/autorot image)]
{:angle (:angle autorot)
:flip (:flip autorot)
:meta (v/metadata autorot)})
;; => {:angle :d0, :flip false, :meta {:width 2490, :height 3084, :bands 3, :has-alpha? false}}
Use these geometry operations when you want to rescale an image first and then work on a precise rectangular region.
(with-open [image (v/from-file "dev/rabbit.jpg")
resized (ops/resize image 0.5)
cropped (ops/extract-area resized 100 100 500 500)]
(v/write-to-file resized "rabbit-resized.jpg")
(v/write-to-file cropped "rabbit-cropped.jpg")
{:resized (v/metadata resized)
:cropped (v/metadata cropped)})
ops/thumbnail exposes libvips’s higher-level thumbnail pipeline. Enum
options such as :size and :crop are documented in ol.vips.enums.
(with-open [thumb (ops/thumbnail "dev/rabbit.jpg" 300
{:height 300
:size :down
:crop :attention})]
(v/write-to-file thumb "rabbit-smart-thumb.jpg")
(v/metadata thumb))
These operations are a good fit for orientation, color interpretation, and other structural changes you want to compose into one pipeline.
(with-open [image (v/from-file "dev/rabbit.jpg")
rotated (ops/rotate image 90.0)
flipped (ops/flip rotated :horizontal)
bw (ops/colourspace flipped :b-w)]
(v/write-to-file bw "rabbit-bw.jpg"))
libvips includes a large set of convolution and enhancement operations, so common blur and sharpen passes can stay inside the same image pipeline.
(with-open [image (v/from-file "dev/rabbit.jpg")
blurred (ops/gaussblur image 3.0)
sharp (ops/sharpen image {:sigma 1.0})]
(v/write-to-file blurred "rabbit-blur.jpg")
(v/write-to-file sharp "rabbit-sharp.jpg")
{:blurred (v/metadata blurred)
:sharp (v/metadata sharp)})
Use the composition helpers when you need to join images, build contact sheets, or align multiple sources into one output image.
(with-open [left (v/from-file "dev/rabbit.jpg")
right (v/from-file "dev/rabbit.jpg")
joined (ops/join left right :horizontal)
grid (ops/arrayjoin [left right left right]
{:across 2
:shim 10
:halign :centre
:valign :centre})]
(v/write-to-file joined "rabbit-joined.jpg")
(v/write-to-file grid "rabbit-grid.jpg"))
The save helpers accept format-specific encoder options, which makes it easy to produce smaller web-friendly JPEG and WebP outputs from the same source image.
(with-open [image (v/from-file "dev/rabbit.jpg")]
(v/write-to-file image "rabbit-progressive.jpg"
{:interlace true
:strip true
:Q 85})
(v/write-to-file image "rabbit.webp"
{:Q 80
:effort 4}))
Use v/call when you want access to the full libvips operation surface
before a dedicated convenience wrapper exists.
(with-open [image (v/from-file "dev/rabbit.jpg")
rotated (v/call "rotate" {:in image :angle 90.0})]
(v/metadata rotated))
Use v/operations to list available libvips operations and
v/operation-info to inspect their inputs and outputs.
Generated operation wrappers also cover image synthesis and compositing, so overlays like text labels can stay inside libvips rather than being rendered in a separate tool.
(with-open [image (v/from-file "dev/rabbit.jpg")
label (ops/text "ol.vips"
{:font "Sans Bold 48"
:rgba true})
poster (ops/composite2 image label :over {:x 40 :y 40})]
(v/write-to-file poster "rabbit-poster.png")
(v/metadata poster))
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |