> ## Documentation Index
> Fetch the complete documentation index at: https://hackmamba-3f164318.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tutorial: Build an Image Processing Pipeline

> Learn to resize, strip metadata, watermark, and convert images by building a reusable processing pipeline.

This tutorial walks you through preparing product photos for an e-commerce site. You will resize images to consistent dimensions, strip metadata that leaks location and device info, add a watermark, convert to WebP for smaller files, and combine everything into a single reusable command.

By the end, you will have a batch script that processes an entire folder of photos in one run.

<Info>
  This tutorial assumes you have ImageMagick installed and have run basic commands. If you haven't, start with [Getting started](/quickstart).
</Info>

<Warning>
  **Shell:** The first five numbered steps below use **bash** (Linux, macOS, or [Git for Windows](https://gitforwindows.org/) Git Bash). Line continuations use `\` at the end of each line; **PowerShell treats `\` differently**, so either paste each command as **one long line** (remove the backslashes and extra newlines) or use **Step 6** for a PowerShell-native loop.
</Warning>

## Set up your working directory

Create a folder for this tutorial and add some test images:

```bash theme={null}
mkdir -p pipeline/originals pipeline/processed
cd pipeline
```

If you have product photos on hand, copy them into `originals/`. If not, create three test images at different sizes to simulate real-world input:

```bash theme={null}
magick -size 2400x1800 plasma:grey80-white originals/input.jpg
magick -size 1800x2400 plasma:grey90-white originals/input-portrait.jpg
magick -size 2000x2000 plasma:grey85-white originals/input-square.jpg
```

These generate textured images at landscape (2400x1800), portrait (1800x2400), and square (2000x2000) dimensions. The exact content doesn't matter for this tutorial. What matters is that they are larger than the 800x800 target and arrive at inconsistent sizes.

Check their dimensions:

```bash theme={null}
magick identify originals/*.jpg
```

Real product photos from different cameras and photographers arrive at different sizes. This pipeline standardizes them.

<Steps>
  <Step title="Step 1: Resize to consistent dimensions">
    E-commerce platforms typically need images at a fixed maximum size. Resize a single image to fit within 800x800 pixels:

    ```bash theme={null}
    magick originals/input.jpg -resize '800x800>' step-resized.jpg
    magick identify step-resized.jpg
    ```

    Example `identify` line (dimensions in field 3; yours may differ slightly by build):

    ```
    step-resized.jpg JPEG 800x600 800x600+0+0 8-bit sRGB 2.34567e+04B 0.000u 0:00.000
    ```

    The third column **`800x600`** confirms your 2400×1800 source was shrunk to fit inside 800×800 (aspect ratio preserved). The resize step uses a trailing greater-than on the geometry so ImageMagick only shrinks: fit inside 800×800, keep aspect ratio, and never upscale a small source. Try the same resize on the other two images to see how portrait and square inputs behave.

    The [Geometry syntax reference](/reference/geometry) covers every modifier in detail.
  </Step>

  <Step title="Step 2: Strip metadata">
    Photos from cameras and phones carry metadata that can include GPS coordinates, device info, and timestamps. For a public storefront, strip it:

    ```bash theme={null}
    magick originals/input.jpg -strip step-stripped.jpg
    magick identify step-stripped.jpg
    ```

    You should still see the same **geometry** as the source (e.g. `800x600` after the earlier resize). Metadata is gone from the file; use `magick identify -verbose step-stripped.jpg | head` if you want to confirm profile/EXIF fields disappeared.
  </Step>

  <Step title="Step 3: Add a watermark">
    Watermarking has two parts: creating the watermark image and compositing it onto the product photo.

    **Create the watermark.** This makes a transparent PNG with white text:

    ```bash theme={null}
    magick -size 300x60 xc:none \
      -fill white -pointsize 28 -gravity center \
      -annotate 0 "SAMPLE" \
      PNG:watermark.png
    ```

    You now have a `watermark.png` with **SAMPLE** on a transparent canvas. **`PNG:`** writes a normal PNG; because the image still has an alpha channel from `xc:none`, transparency is kept. Use **`PNG32:watermark.png`** instead if you ever need to **force** a 32-bit RGBA file on disk (some older tools expect that explicit depth).

    **Tweak the label:** change the string in quotes, or adjust color, size, and font:

    ```bash theme={null}
    magick -size 360x80 xc:none -fill "#c62828" -pointsize 36 -font "Helvetica-Bold" \
      -gravity center -annotate 0 "DRAFT" PNG:watermark-red.png
    ```

    Use your own font name (see `magick -list font`) and point size so the watermark fits your product frame.

    **Apply the watermark.** Composite it onto a product photo, positioned in the bottom-right corner:

    ```bash theme={null}
    magick originals/input.jpg watermark.png \
      -gravity SouthEast -geometry +20+20 \
      -composite step-watermarked.jpg
    magick identify step-watermarked.jpg
    ```

    Example (geometry should match your resized photo; JPEG because this step still writes `.jpg`):

    ```
    step-watermarked.jpg JPEG 800x600 800x600+0+0 8-bit sRGB …
    ```

    The `-gravity SouthEast -geometry +20+20` places the watermark 20 pixels from the bottom-right edges.
  </Step>

  <Step title="Step 4: Convert to WebP">
    WebP produces smaller files than JPEG at comparable visual quality. Convert an image and set the compression level:

    ```bash theme={null}
    magick originals/input.jpg -quality 85 preview.webp
    magick identify preview.webp
    ```

    Example (this step reads the **original** full-size JPEG, so dimensions stay large until Step 5):

    ```
    preview.webp WEBP 2400x1800 2400x1800+0+0 8-bit sRGB …
    ```

    ImageMagick determines the output format from the `.webp` extension. The **`-quality`** value controls lossy compression for that write; see [-quality](/reference/common-options#quality) for how to choose numbers across JPEG and WebP.
  </Step>

  <Step title="Step 5: Combine everything into one command">
    Each step you have learned so far is an operation that ImageMagick processes left to right. You can combine them all into a single `magick` call. In bash, `\` must be the **last** character on a line; do not put inline `#` comments after a continuation backslash.

    **Full pipeline (copy-paste):**

    ```bash theme={null}
    magick originals/input.jpg \
      -resize '800x800>' \
      -strip \
      watermark.png \
      -gravity SouthEast -geometry +20+20 \
      -composite \
      -quality 85 \
      processed/input.webp
    ```

    **Walk the combined command (read in order):**

    1. **Load:** `magick originals/input.jpg` with a line continuation (backslash as the last character on the line) so the pipeline can span multiple lines.
    2. **Resize (operator):** `-resize '800x800>'` runs here: it shrinks large photos to fit inside the box while preserving aspect ratio, and it does not upscale smaller sources.
    3. **Strip (operator):** `-strip` removes EXIF, comments, and color profiles you usually do not want on public web assets, applied as soon as it is reached.
    4. **Second input:** `watermark.png` pushes a second image onto the stack so the next operators can composite it onto the base photo.
    5. **Position:** `-gravity SouthEast -geometry +20+20` anchors the watermark **20px** from the bottom-right edges of the resized photo.
    6. **Composite (operator):** `-composite` merges the overlay with the base image using the current gravity and geometry at this point in the command.
    7. **Quality (setting):** `-quality 85` sets WebP compression for the next lossy write (this repo uses **85** as a shared default in examples; tune as needed; see [-quality](/reference/common-options#quality)).
    8. **Write:** `processed/input.webp` is the output path; ImageMagick determines the encoder from the `.webp` extension.

    See also the [common options reference](/reference/common-options) for deeper notes on these flags.

    Verify the result:

    ```bash theme={null}
    magick identify processed/input.webp
    ```

    Example line:

    ```
    processed/input.webp WEBP 800x600 800x600+0+0 8-bit sRGB …
    ```

    The **WEBP** token and **`800x600`** (or your aspect-correct size) confirm the pipeline wrote a WebP at the expected dimensions. One command turns a raw product photo into a web-ready, watermarked, metadata-free WebP.
  </Step>

  <Step title="Step 6: Batch-process a folder">
    Wrap the pipeline in a loop to process every image in the `originals/` folder:

    <Tabs>
      <Tab title="Linux / macOS">
        ```bash theme={null}
        for file in originals/*.jpg; do
          filename=$(basename "$file" .jpg)
          magick "$file" \
            -resize '800x800>' \
            -strip \
            watermark.png \
            -gravity SouthEast -geometry +20+20 \
            -composite \
            -quality 85 \
            "processed/${filename}.webp"
          echo "Done: $file -> processed/${filename}.webp"
        done
        ```
      </Tab>

      <Tab title="Windows (PowerShell)">
        ```powershell theme={null}
        Get-ChildItem originals\*.jpg | ForEach-Object {
          $outName = $_.BaseName + ".webp"
          magick $_.FullName `
            -resize "800x800>" `
            -strip `
            watermark.png `
            -gravity SouthEast -geometry +20+20 `
            -composite `
            -quality 85 `
            "processed\$outName"
          Write-Host "Done: $($_.Name) -> processed\$outName"
        }
        ```
      </Tab>
    </Tabs>

    After the loop finishes, check the results:

    ```bash theme={null}
    magick identify processed/*.webp
    ```

    Each output image fits within 800x800, has no metadata, carries a watermark, and is compressed as WebP.
  </Step>
</Steps>

## Clean up

Remove the intermediate test files you created during the tutorial:

```bash theme={null}
rm -f step-resized.jpg step-stripped.jpg step-watermarked.jpg preview.webp
```

Keep the `watermark.png`, `originals/`, and `processed/` folders. The watermark and the batch script are reusable for future product photo batches.

## Next steps

This tutorial covered resizing with only-shrink geometry, stripping metadata with `-strip`, building a simple watermark with `xc:none` and `-annotate`, compositing with `-gravity` / `-geometry` / `-composite`, writing WebP with `-quality`, and chaining those pieces into one `magick` line. Here is where to go next:

* [Batch resize and optimize for web](/how-to/batch-resize-and-optimize) for subdirectory trees, JPEG file-size ceilings, and more resize modes in production scripts.
* [Geometry syntax reference](/reference/geometry) for every resize modifier on dimension strings.
* [Common options reference](/reference/common-options) for `-strip`, `-quality`, `-composite`, and related flags in one place.
* [Install and first commands](/quickstart) if you need to revisit operators vs. settings or installation checks.
