# How the Seam Carving Image Resizing Algorithm Is Implemented in trekhleb/javascript-algorithms

> Explore the Seam Carving algorithm implementation in javascript-algorithms. Learn content-aware image resizing via energy maps, seam selection, and removal.

- Repository: [Oleksii Trekhleb/javascript-algorithms](https://github.com/trekhleb/javascript-algorithms)
- Tags: how-to-guide
- Published: 2026-02-24

---

**The Seam Carving image resizing algorithm in this repository implements content-aware image reduction through an energy-map generation, dynamic-programming seam selection, and in-place seam removal pipeline.**

The Seam Carving image resizing algorithm intelligently reduces image dimensions by removing paths of least importance rather than uniformly scaling or cropping. In the `trekhleb/javascript-algorithms` repository, this computer vision technique is implemented in pure JavaScript within [`src/algorithms/image-processing/seam-carving/resizeImageWidth.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/image-processing/seam-carving/resizeImageWidth.js). The solution processes **ImageData** objects directly, using a deterministic three-stage approach that preserves visually significant content while shrinking width iteratively.

## Energy Map Generation

The algorithm begins by quantifying visual importance through an **energy map** calculation. For each pixel, the implementation computes a simple horizontal gradient energy defined as the squared color difference between the immediate left and right neighbors.

In [`resizeImageWidth.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/resizeImageWidth.js) (lines 92-108), the `calculateEnergyMap` function iterates over every `(x, y)` coordinate in the image. It extracts pixel colors using the `getPixel` utility from [`src/algorithms/image-processing/utils/imageData.js`](https://github.com/trekhleb/javascript-algorithms/blob/main/src/algorithms/image-processing/utils/imageData.js), computes the energy via `getPixelEnergy`, and populates a 2-D `EnergyMap` array. This matrix serves as the foundation for identifying which pixels contribute least to the image's visual structure.

## Finding the Lowest-Energy Vertical Seam

With the energy map established, the algorithm employs **dynamic programming** to locate the vertical seam—an 8-connected path of pixels from top to bottom—with the minimum total energy. This step ensures that the removed pixels introduce the least visual distortion.

The `findLowEnergySeam` function (lines 117-194) constructs a `seamPixelsMap` table that stores two critical values for each pixel: the cumulative minimum energy required to reach that pixel from the top row, and a back-pointer to the previous pixel in the optimal path. The implementation initializes the first row with raw energy values, then for each subsequent row selects the smallest-energy predecessor among three possible upper neighbors (`x-1`, `x`, `x+1`). After filling the table, the algorithm back-tracks from the minimum-energy pixel in the bottom row to reconstruct the complete seam path.

## In-Place Seam Removal

Once identified, the seam must be excised efficiently without allocating new memory buffers. The `deleteSeam` function (lines 202-209) performs this deletion by shifting every pixel to the right of the seam one position leftward, effectively shortening each row by one pixel.

Using the `setPixel` utility, the implementation copies the neighbor pixel's color into the current position as it walks the seam from top to bottom. This approach modifies the underlying `Uint8ClampedArray` buffer in-place, maintaining the original **ImageData** object reference while reducing the logical width. The algorithm thus avoids the performance overhead of buffer reallocation during iterative resizing operations.

## Iterative Width Reduction

The `resizeImageWidth` entry point (lines 225-244) orchestrates the complete resizing operation by calculating the number of columns to remove: `pxToRemove = img.width - toWidth`. It then repeats the **energy-map → seam selection → seam deletion** cycle exactly `pxToRemove` times.

After each iteration, the stored image size (`size.w`) decrements by one, reflecting the new logical width. The original `ImageData` buffer persists throughout the process, with pixels compacted leftward continuously until the target dimensions are achieved. This iterative approach ensures that energy is recalculated after each seam removal, adapting to the changing image structure dynamically.

## Practical Implementation Example

The following example demonstrates how to resize an image width using the repository's implementation:

```javascript
import resizeImageWidth from
  'javascript-algorithms/src/algorithms/image-processing/seam-carving/resizeImageWidth';

// Assume `originalImg` is an ImageData object (e.g., from a canvas).
const targetWidth = 300;                // Desired width
const { img: resizedImg, size } = resizeImageWidth({
  img: originalImg,
  toWidth: targetWidth,
});

// `resizedImg` holds the same Uint8ClampedArray buffer, now representing
// an image of width `size.w` (the new width) and unchanged height.

```

The `resizedImg` object contains the modified pixel data, while `size.w` reports the new width. The height remains unchanged throughout the Seam Carving process.

## Summary

- **Energy calculation** uses horizontal gradients (squared color differences) to identify low-importance pixels in `calculateEnergyMap` (lines 92-108).
- **Dynamic programming** in `findLowEnergySeam` (lines 117-194) determines the optimal vertical seam by tracking cumulative energy and back-pointers across the `seamPixelsMap` table.
- **In-place modification** via `deleteSeam` (lines 202-209) shifts pixels leftward without reallocating the ImageData buffer, using `setPixel` to overwrite seam pixels.
- **Iterative execution** in `resizeImageWidth` (lines 225-244) repeats the pipeline until the target width is reached, adjusting logical dimensions after each seam removal.

## Frequently Asked Questions

### How does the algorithm determine which pixels are safe to remove?

The algorithm computes an energy map where each pixel's value represents the squared color difference between its left and right neighbors. Pixels with low energy values—typically located in smooth, low-contrast regions—are prioritized for removal, while high-energy edges and detailed textures are preserved.

### Why does the implementation use dynamic programming to find seams?

Dynamic programming solves the optimal seam finding problem efficiently by exploiting the optimal substructure property: the minimum energy path to any pixel depends only on the minimum energy paths to its three upper neighbors. This reduces the time complexity from exponential to O(width × height), making real-time processing feasible.

### Does the Seam Carving algorithm modify the original ImageData buffer?

Yes, the implementation modifies the pixel data in-place within the existing `Uint8ClampedArray` buffer. The `deleteSeam` function shifts subsequent pixels leftward to overwrite removed seam pixels, avoiding memory reallocation. However, the original ImageData object reference remains valid; only the logical width (`size.w`) and pixel array contents change.

### What type of energy function does this JavaScript implementation use?

The repository uses a simple **horizontal gradient energy function** that calculates the squared Euclidean distance between a pixel's left and right RGB neighbors. This computationally inexpensive metric effectively identifies vertical edges and textures that should be preserved during width reduction.