Docs / Cropping

Cropping v0.2.0

crop= cuts a region out of the source before anything gets resized. Its sizes and offsets are in source pixels, and the output parameters (w, h, ar, fit and pad) are applied to the region afterwards.

/photo.jpg?crop=w:800|h:600|g:center&w=400

The crop parameter

Write it as key:value pairs joined with |. Short and long key names both work, but keys are case-sensitive. You need at least one of w, h or ar.

w width

Width of the region in source pixels.

h height

Height of the region in source pixels.

ar aspect_ratio

Aspect ratio of the region.

g gravity

Where the region sits, or how it's chosen.

x

Moves the region horizontally from where gravity put it.

y

Moves the region vertically from where gravity put it.

w:0, h:0 and empty values count as unset. A crop with only placement keys, like crop=g:center|x:20, is rejected, and so are unknown keys, malformed pairs and invalid values.

/photo.jpg?crop=width:800|height:600|gravity:top-left
/photo.jpg?crop=ar:16/9

Choosing the region size

The keys you set decide the size of the region:

  • w and h together give that exact size, and ar is ignored.
  • Only one of them, without ar: the other side spans the whole source.
  • Only one of them, with ar: the other side comes from the ratio.
  • ar alone: the largest region of that ratio that fits in the source.

ar takes auto, square, video, or a fraction such as 4/3 or 16/9. Custom ratios must be fractions: ar:1 is rejected, ar:1/1 and ar:square are fine.

Here’s what that looks like on a 1000 × 600 source:

w:400
h:200
w:400|ar:2/1
ar:square

Ask for a region bigger than the source and it’s simply trimmed to the source, not rejected.

Gravity and offsets

g positions the region inside the source:

top · right · bottom · left · top-left · top-right · bottom-left · bottom-right · center · attention · entropy

It defaults to image.crop_gravity, which is center unless you’ve changed it. This is separate from the top-level g / gravity that fit=cover and fit=contain use.

Once gravity has placed the region, x nudges it right and y nudges it down; negative values go left or up. The region never slides past the edge of the source.

/photo.jpg?crop=w:800|h:600|g:top-left
/photo.jpg?crop=w:800|h:600|g:center|x:100|y:-50
/photo.jpg?crop=w:800|h:600|g:bottom-right

Smart crop

g:attention goes for the most eye-catching detail, g:entropy for the busiest part of the image. libvips picks the position itself, so x and y are ignored.

/portrait.jpg?crop=ar:square|g:attention&w=600
/texture.jpg?crop=w:800|h:450|g:entropy

On an animation the crop runs on every frame, and smart crop picks a spot separately for each one. If the region mustn’t move between frames, use a fixed gravity.

Crop, then size

crop= and fit=cover do different jobs. crop= picks the part of the source to work with; w, h, ar and fit then decide what the output made from it looks like.

Raster transform order
  1. Autorotate
    / rotate
  2. Crop
  3. Size × DPR
    × scale
  4. Fit
    / gravity
  5. Pad
  6. Filters
  7. Watermark

The later stages are covered in Filters & effects and Watermarking.

Rotation happens first, so crop coordinates refer to the image after EXIF orientation and rot have been applied. dpr and scale don’t touch crop values; they stay in source pixels.

# Cut an 800 × 600 region, then resize it to 400 × 300.
/photo.jpg?crop=w:800|h:600|g:center&w=400&h=300

# Take the largest square, then make a 600 × 400 cover output from it.
/photo.jpg?crop=ar:square&w=600&h=400&fit=cover&g=top

The crop also applies to each video frame or clip and each frame of an animated image. It’s skipped when picturium returns the original file or a document with f=pdf or f=svg.

For what happens to the region afterwards, see Sizing & layout.