Skip to content

Smart crop, gravity, and automatic border trim

Copy page

When an input image’s aspect ratio differs from the target card, libvips offers two content-aware cropping capabilities beyond simple centre cropping:

  1. Smart focal cropping (smartcrop / Interesting): evaluates Shannon information entropy (entropy) or visual salience (attention) to locate and keep the most informative rectangle.
  2. Automatic solid/transparent border trimming (find_trim / trim): detects uniform margins matching a background colour and returns the tight bounding box (left, top, width, height) — ideal for e-commerce product shots and padded icons.

Comparing centre, directional, and entropy crops

Section titled “Comparing centre, directional, and entropy crops”

These three 600 × 300 outputs are generated from the same 1938 × 1292 source photograph, comparing geometric centre (centre), low-coordinate gravity (north / low), and entropy-guided cropping (entropy):

600×300 night scene cropped around the geometric centre
cover centre600 × 300, 33,898 bytes
600×300 night scene keeping the upper arch crown
cover north (low)600 × 300, 29,562 bytes
600×300 night scene cropped by Shannon entropy
cover entropy600 × 300, 33,656 bytes

Standalone SmartCrop (Entropy vs Attention)

Section titled “Standalone SmartCrop (Entropy vs Attention)”

When you need content-aware cropping directly on an open image (outside of a thumbnail loader), call SmartCrop (vips_smartcrop):

  • InterestingEntropy (entropy): divides the image into sections, measures Shannon entropy, and keeps the region with the richest edge and texture detail.
  • InterestingAttention (attention): weights high saturation, luminance contrast, and skin-tone heuristics, making it well suited for portraits and focal subjects.
package main
import (
"fmt"
"os"
"github.com/davidbyttow/govips/v2/vips"
)
func main() {
if err := vips.Startup(nil); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer vips.Shutdown()
image, err := vips.NewImageFromFile("input.jpg")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer image.Close()
// Crop a 600×300 region around the highest visual attention area
if err := image.SmartCrop(600, 300, vips.InterestingAttention); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
data, _, err := image.ExportWebp(vips.NewWebpExportParams())
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if err := os.WriteFile("smart-attention.webp", data, 0o644); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
Crop focus intent govips vips.Interesting sharp position pyvips / vips CLI
Do not crop (proportional fit) vips.InterestingNone fit: 'inside' "none"
Geometric centre vips.InterestingCentre 'centre' / 'center' "centre"
Bias toward low coordinates (top or left) vips.InterestingLow 'north' or 'west' "low"
Bias toward high coordinates (bottom or right) vips.InterestingHigh 'south' or 'east' "high"
Highest Shannon entropy vips.InterestingEntropy sharp.strategy.entropy / 'entropy' "entropy"
Highest visual salience vips.InterestingAttention sharp.strategy.attention / 'attention' "attention"

Automatic solid or transparent border trimming (FindTrim / trim)

Section titled “Automatic solid or transparent border trimming (FindTrim / trim)”

To strip uniform white, coloured, or transparent borders around product photographs or scanned documents, use find_trim to locate the bounding box (left, top, width, height) of non-background pixels:

  • govips, pyvips, and vips CLI use a two-step pattern: call FindTrim / find_trim to compute the bounding box, check that width > 0 && height > 0, and then call ExtractArea / crop.
  • sharp provides a single-step .trim({ background, threshold }) method and reports trimOffsetLeft and trimOffsetTop in OutputInfo.
// Locate the bounding box where pixels differ from white (#FFFFFF) by more than threshold=10
bg := &vips.Color{R: 255, G: 255, B: 255}
left, top, width, height, err := image.FindTrim(10.0, bg)
if err != nil {
return err
}
if width <= 0 || height <= 0 {
return fmt.Errorf("entire image matched background threshold")
}
// Crop to the detected bounding box
if err := image.ExtractArea(left, top, width, height); err != nil {
return err
}