Skip to content
Seam Carving in Rust
Branch: master
Clone or download
elfsternberg REFACTOR Break the energy-of-pixels function out
The function energy_of_pixel_pair is a concrete implementation of a
family of algorithms for calculating the distance between to pixels
in a given energy.  Making them their own module decouples their
implementation from the signature as used by the various seamfinder
Latest commit 1b11f5d Oct 14, 2019

pnmseam - scale a portable anymap using seam carving

pnmseam is a library and accompanying command line program to scale any pnm (portable anymap) file using the seamcarving algorithm. Several variants of the seamcarving algorithm are supplied. By default the algorithms are single-threaded, but multithread capability is available as a compile-time option.


pnmseam -s --scale [pnmfile]
pnmseam -r --reduce [pnmfile]
pnmseam -z --xysize rows cols [pnmfile]
pnmseam -p --pixels s [pnmfile]
pnmseam -o [output file]
pnmseam --fsc
pnmseam --fgsc


This is very much a work in progress. The above commands do not work, and the output filename is hard-coded for testing purposes. That said, the AviSha1 and AviSha2 algorithms work as advertised.


pnmseam attempts to resize an image using the algorithms described in Avidan & Shamir's paper Seam Carving for Content-Aware Image Resizing and subsequent research, and can use both the Basic Seam Carving (BSC) algorithm (the default), the Forward Seam Carving (FSC) algorithm, or the Flow-Guiding Seam Carving (FGSC) algorithm.

Seam carving algorithms use a gradient process to calculate a "seam" (a wandering path of pixels traversing from left-to-right or top-to-bottom) that can be removed from the image causing the minimal amount of damage to the original. The seams are chosen based upon how little the image would change if the seam is removed. In some cases, this can result in a dramatic cropping and repositioning of the image with the main subject left untouched; in others, it can cause significant distortion.

The seam carving algorithms are intended primarily to downscale images. In the event that the request upscales an image, the algorithm calculates as many seams as necessary to upscale the image and then processes them from highest to lowest energy, for each creating an interstitial seam that is the average of its neighbors. As with downsizing, this can create significant distortion.

Project interim notes

The basic premise of this program is that a picture file is a collection of pixels. (This isn't necessarily true for some image formats, most notoriously JPEG, but it's true enough to make it worthwhile, and even JPEGs are rendered as pixels for purposes of editing.)

The steps therefore are:

  • Image -> Energy Map -> Seam Collection -> Lowest Energy Seam
  • LowestEnergySeam + Image -> New Image


Images aren't generic. They came in Luma (greyscale) and RGB formats, along with their alpha channel variants. For our purposes, we're not going to handle alpha channel, since the alpha channel doesn't make sense for our purposes. Mapping from/to the image in a generic way is our biggest headache.

The task isn't generic, either. The image can be read-only, but we can only work with so much in a thread-based fashion.

The other challenge is just the number of different integer types involved in doing this work. image-rs indexes the (x, y) pair of any image as u32, but we know damn well that under the covers it's really a usize-mapped index into a vec. Making that work repeatedly is the big challenge.


  • Write AviShaTwo (forward energy)
  • Actually implement pamseam arguments in clap!
  • Look at other algorithms in AviShaOne
  • implement caching.
  • implement hori/vert mirrors.
  • implement threading.
  • Begin C implementation of AviShaOne


There are two features not enabled by default.

cargo build --features=threaded will provide the -t --threads [threadcount] option, which will use as many threads as specified to generate the energy map and seam selection list, but will not exceed the CPU count provided by the OS.

cargo build --features=square_root will use a floating point-based energy calculation function. This is significantly slower, but it has been reported that this creates better results when working with relatively small original files (images less that 800x600 pixels).



pnmseam is Copyright Elf M. Sternberg (c) 2019, and licensed with the Mozilla Public License vers. 2.0. A copy of the license file is included in the root folder.

You can’t perform that action at this time.