# Convert, resize, or watermark images

Robot: `/image/resize`

🤖/image/resize resizes, crops, changes colorization, rotation, and applies text and watermarks to images.

Stage: ga

## Usage example

Resize uploaded images to a width of 200px while keeping their original aspect ratio:

```json
{
  "steps": {
    "resized": {
      "robot": "/image/resize",
      "use": ":original",
      "width": 200
    }
  }
}
```

## Parameters

* `interpolate`: Controls whether Assembly Variables are interpolated for individual instruction fields.

  By default, most Robot instruction fields interpolate Assembly Variables. Set this to `false` to treat every instruction field as literal text, or set an individual field path to `false` to treat only that field as literal text. For Robot-specific fields that are literal by default, set this to `true` or set that field path to `true` to opt back into interpolation.

  Use field names such as `path`, or dotted paths such as `ffmpeg.vf` for nested objects.

* `output_meta`: Allows you to specify a set of metadata that is more expensive on CPU power to calculate, and thus is disabled by default to keep your Assemblies processing fast.

  For images, you can add `"has_transparency": true` in this object to extract if the image contains transparent parts and `"dominant_colors": true` to extract an array of hexadecimal color codes from the image.

  For images, you can also add `"blurhash": true` to extract a [BlurHash](https://blurha.sh) string — a compact representation of a placeholder for the image, useful for showing a blurred preview while the full image loads.

  For videos, you can add the `"colorspace": true` parameter to extract the colorspace of the output video.

  For videos, you can also add `"interlaced": true` to detect whether the video is interlaced. This combines the cheap ffprobe `field_order` flag with a bounded `idet` sampling pass over the first frames of the source, exposing `interlaced`, `field_order`, and a diagnostic `interlace_detection` object under `file.meta`. This is computationally expensive and billed accordingly.

  For audio, you can add `"mean_volume": true` to get a single value representing the mean average volume of the audio file.

  You can also set this to `false` to skip metadata extraction and speed up transcoding.

* `result`: Whether the results of this Step should be present in the Assembly Status JSON

* `queue`: Setting the queue to 'batch', manually downgrades the priority of jobs for this step to avoid consuming Priority job slots for jobs that don't need zero queue waiting times

* `force_accept`: Force a Robot to accept a file type it would have ignored.

  By default, Robots ignore files they are not familiar with.
  [🤖/video/encode](/docs/robots/video-encode.md), for
  example, will happily ignore input images.

  With the `force_accept` parameter set to `true`, you can force Robots to accept all files thrown at them.
  This will typically lead to errors and should only be used for debugging or combatting edge cases.

* `ignore_errors`: Ignore errors during specific phases of processing.

  Setting this to `["meta"]` will cause the Robot to ignore errors during metadata extraction.

  Setting this to `["execute"]` will cause the Robot to ignore errors during the main execution phase.

  Setting this to `true` is equivalent to `["meta", "execute"]` and will ignore errors in both phases.

* `use`: Specifies which Step(s) to use as input.

  * You can pick any names for Steps except `":original"` (reserved for user uploads handled by Transloadit)
  * You can provide several Steps as input with arrays:
    ```json
    {
      "use": [
        ":original",
        "encoded",
        "resized"
      ]
    }
    ```
  * You can also tag input Steps with `as` to pass semantic intent to robots:
    ```json
    {
      "use": [
        {
          "name": ":original",
          "as": "image"
        },
        {
          "name": ":original",
          "as": "mask"
        }
      ]
    }
    ```

  > [!Tip]
  > That's likely all you need to know about `use`, but you can view [Advanced use cases](/docs/topics/use-parameter.md).

* `imagemagick_stack`

* `format`: The output format for the modified image.

  Some of the most important available formats are `"jpg"`, `"png"`, `"gif"`, `"tiff"`, and `"jxl"` for JPEG XL. For a complete list of all formats that we can write to, please check [our supported image formats list](/docs/supported-formats/image-formats.md).

  If `null` (default), then the input image's format will be used as the output format.

  If you wish to convert to `"pdf"`, please consider [🤖/document/convert](/docs/robots/document-convert.md) instead.

* `width`: Width of the result in pixels. If not specified, will default to the width of the original.

* `height`: Height of the new image, in pixels. If not specified, will default to the height of the input image.

* `resize_strategy`: See the list of available [resize strategies](/docs/topics/resize-strategies.md).

* `zoom`: If this is set to `false`, smaller images will not be stretched to the desired width and height. For details about the impact of zooming for your preferred resize strategy, see the list of available [resize strategies](/docs/topics/resize-strategies.md).

* `crop`: Specify an object containing coordinates for the top left and bottom right corners of the rectangle to be cropped from the original image(s). The coordinate system is rooted in the top left corner of the image. Values can be integers for absolute pixel values or strings for percentage based values.

  For example:

  ```json
  {
    "x1": 80,
    "y1": 100,
    "x2": "60%",
    "y2": "80%"
  }
  ```

  This will crop the area from `(80, 100)` to `(600, 800)` from a 1000×1000 pixels image, which is a square whose width is 520px and height is 700px. If `crop` is set, the width and height parameters are ignored, and the `resize_strategy` is set to `crop` automatically.

  You can also use a JSON string of such an object with coordinates in similar fashion:

  ```json
  "{\"x1\": <Integer>, \"y1\": <Integer>, \"x2\": <Integer>, \"y2\": <Integer>}"
  ```

  To crop around human faces, see [🤖/image/facedetect](/docs/robots/image-facedetect.md).

* `gravity`: The direction from which the image is to be cropped when `"resize_strategy"` is set to `"crop"` or `"fillcrop"`, but no crop coordinates are defined.

  You can also use `"entropy"` or `"attention"` for automatic point-of-interest cropping. `"entropy"` keeps the region with the highest Shannon entropy, while `"attention"` favors areas with luminance frequency, saturation, and skin-tone cues.

* `strip`: Strips all metadata from the image. This is useful to keep thumbnails as small as possible.

* `alpha`: Gives control of the alpha/matte channel of an image.

* `preclip_alpha`: Gives control of the alpha/matte channel of an image before applying the clipping path via `clip: true`.

* `flatten`: Flattens all layers onto the specified background to achieve better results from transparent formats to non-transparent formats, as explained in the [ImageMagick documentation](https://www.imagemagick.org/script/command-line-options.php#layers).

  To preserve animations, GIF files are not flattened when this is set to `true`. To flatten GIF animations, use the `frame` parameter.

* `correct_gamma`: Prevents gamma errors [common in many image scaling algorithms](https://www.4p8.com/eric.brasseur/gamma.html).

* `quality`: Controls the image compression for JPG and PNG images. Please also take a look at [🤖/image/optimize](/docs/robots/image-optimize.md).

* `adaptive_filtering`: Controls the image compression for PNG images. Setting to `true` results in smaller file size, while increasing processing time. It is encouraged to keep this option disabled.

* `background`: Either the hexadecimal code or [name](https://www.imagemagick.org/script/color.php#color_names) of the color used to fill the background (used for the `pad` resize strategy).

  **Note:** By default, the background of transparent images is changed to white. To preserve transparency, set `"background"` to `"none"`.

* `frame`: Use this parameter when dealing with animated GIF files to specify which frame of the GIF is used for the operation. Specify `1` to use the first frame, `2` to use the second, and so on. `null` means all frames.

* `colorspace`: Sets the image colorspace. For details about the available values, see the [ImageMagick documentation](https://www.imagemagick.org/script/command-line-options.php#colorspace). Please note that if you were using `"RGB"`, we recommend using `"sRGB"` instead as of 2014-02-04. ImageMagick might try to find the most efficient `colorspace` based on the color of an image, and default to e.g. `"Gray"`. To force colors, you might have to use this parameter in combination with `type: "TrueColor"`.

* `type`: Sets the image color type. For details about the available values, see the [ImageMagick documentation](https://www.imagemagick.org/script/command-line-options.php#type). If you're using `colorspace`, ImageMagick might try to find the most efficient based on the color of an image, and default to e.g. `"Gray"`. To force colors, you could e.g. set this parameter to `"TrueColor"`

* `sepia`: Applies a sepia tone effect in percent.

* `rotation`: Determines whether the image should be rotated. Use any number to specify the rotation angle in degrees (e.g., `90`, `180`, `270`, `360`, or precise values like `2.9`). Use the value `true` or `"auto"` to auto-rotate images that are rotated incorrectly or depend on EXIF rotation settings. Otherwise, use `false` to disable auto-fixing altogether.

* `compress`: Specifies pixel compression for when the image is written. Compression is disabled by default.

  Please also take a look at [🤖/image/optimize](/docs/robots/image-optimize.md).

* `blur`: Specifies gaussian blur, using a value with the form `{radius}x{sigma}`. The radius value specifies the size of area the operator should look at when spreading pixels, and should typically be either `"0"` or at least two times the sigma value. The sigma value is an approximation of how many pixels the image is "spread"; think of it as the size of the brush used to blur the image. This number is a floating point value, enabling small values like `"0.5"` to be used.

* `blur_regions`: Specifies an array of ellipse objects that should be blurred on the image. Each object has the following keys: `x`, `y`, `width`, `height`.  If `blur_regions` has a value, then the `blur` parameter is used as the strength of the blur for each region.

* `brightness`: Increases or decreases the brightness of the image by using a multiplier. For example `1.5` would increase the brightness by 50%, and `0.75` would decrease the brightness by 25%.

* `saturation`: Increases or decreases the saturation of the image by using a multiplier. For example `1.5` would increase the saturation by 50%, and `0.75` would decrease the saturation by 25%.

* `hue`: Changes the hue by rotating the color of the image. The value `100` would produce no change whereas `0` and `200` will negate the colors in the image.

* `contrast`: Adjusts the contrast of the image. A value of `1` produces no change. Values below `1` decrease contrast (with `0` being minimum contrast), and values above `1` increase contrast (with `2` being maximum contrast). This works like the `brightness` parameter.

* `watermark_url`: A URL indicating a PNG image to be overlaid above this image. Please note that you can also  [supply the watermark via another Assembly Step](/docs/topics/use-parameter.md#supplying-the-watermark-via-an-assembly-step). With watermarking you can add an image onto another image. This is usually used for logos.

* `watermark_position`: The position at which the watermark is placed. The available options are `"center"`, `"top"`, `"bottom"`, `"left"`, and `"right"`. You can also combine options, such as `"bottom-right"`.

  An array of possible values can also be specified, in which case one value will be selected at random, such as `[ "center", "left", "bottom-left", "bottom-right" ]`.

  This setting puts the watermark in the specified corner. To use a specific pixel offset for the watermark, you will need to add the padding to the image itself.

* `watermark_x_offset`: The x-offset in number of pixels at which the watermark will be placed in relation to the position it has due to `watermark_position`.

  Values can be both positive and negative and yield different results depending on the `watermark_position` parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point.

* `watermark_y_offset`: The y-offset in number of pixels at which the watermark will be placed in relation to the position it has due to `watermark_position`.

  Values can be both positive and negative and yield different results depending on the `watermark_position` parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point.

* `watermark_size`: The size of the watermark, as a percentage.

  For example, a value of `"50%"` means that size of the watermark will be 50% of the size of image on which it is placed. The exact sizing depends on `watermark_resize_strategy`, too.

* `watermark_resize_strategy`: Available values are `"fit"`, `"min_fit"`, `"stretch"` and `"area"`.

  To explain how the resize strategies work, let's assume our target image size is 800×800 pixels and our watermark image is 400×300 pixels. Let's also assume, the `watermark_size` parameter is set to `"25%"`.

  For the `"fit"` resize strategy, the watermark is scaled so that the longer side of the watermark takes up 25% of the corresponding image side. And the other side is scaled according to the aspect ratio of the watermark image. So with our watermark, the width is the longer side, and 25% of the image size would be 200px. Hence, the watermark would be resized to 200×150 pixels. If the `watermark_size` was set to `"50%"`, it would be resized to 400×300 pixels (so just left at its original size).

  For the `"min_fit"` resize strategy, the watermark is scaled so that the shorter side of the watermark takes up 25% of the corresponding image side. And the other side is scaled according to the aspect ratio of the watermark image. So with our watermark, the height is the shorter side, and 25% of the image size would be 200px. Hence, the watermark would be resized to 267×200 pixels. If the `watermark_size` was set to `"50%"`, it would be resized to 533×400 pixels (so larger than its original size).

  For the `"stretch"` resize strategy, the watermark is stretched (meaning, it is resized without keeping its aspect ratio in mind) so that both sides take up 25% of the corresponding image side. Since our image is 800×800 pixels, for a watermark size of 25% the watermark would be resized to 200×200 pixels. Its height would appear stretched, because keeping the aspect ratio in mind it would be resized to 200×150 pixels instead.

  For the `"area"` resize strategy, the watermark is resized (keeping its aspect ratio in check) so that it covers `"xx%"` of the image's surface area. The value from `watermark_size` is used for the percentage area size.

* `watermark_opacity`: The opacity of the watermark, where `0.0` is fully transparent and `1.0` is fully opaque.

  For example, a value of `0.5` means the watermark will be 50% transparent, allowing the underlying image to show through. This is useful for subtle branding or when you want the watermark to be less obtrusive.

* `watermark_repeat_x`: When set to `true`, the watermark will be repeated horizontally across the entire width of the image.

  This is useful for creating tiled watermark patterns that cover the full image and make it more difficult to crop out the watermark.

* `watermark_repeat_y`: When set to `true`, the watermark will be repeated vertically across the entire height of the image.

  This is useful for creating tiled watermark patterns that cover the full image. Can be combined with `watermark_repeat_x` to tile in both directions.

* `text`: Text overlays to be applied to the image. Can be either a single text object or an array of text objects. Each text object contains text rules. The following text parameters are intended to be used as properties for your text overlays. Here is an example:

  ```json
  "watermarked": {
    "use": "resized",
    "robot": "/image/resize",
    "text": [
      {
        "text": "© 2018 Transloadit.com",
        "size": 12,
        "font": "Ubuntu",
        "color": "#eeeeee",
        "valign": "bottom",
        "align": "right",
        "x_offset": 16,
        "y_offset": -10
      }
    ]
  }
  ```

* `progressive`: Interlaces the image if set to `true`, which makes the image load progressively in browsers. Instead of rendering the image from top to bottom, the browser will first show a low-res blurry version of the images which is then quickly replaced with the actual image as the data arrives. This greatly increases the user experience, but comes at a cost of a file size increase by around 10%.

* `transparent`: Make this color transparent within the image. Example: `"255,255,255"`.

* `trim_whitespace`: This determines if additional whitespace around the image should first be trimmed away. If you set this to `true` this parameter removes any edges that are exactly the same color as the corner pixels.

* `clip`: Apply the clipping path to other operations in the resize job, if one is present. If set to `true`, it will automatically take the first clipping path. If set to a String it finds a clipping path by that name.

* `negate`: Replace each pixel with its complementary color, effectively negating the image. Especially useful when testing clipping.

* `clut`: Applies a Color Look-Up Table (CLUT) image to remap the colors of the input image using ImageMagick's `-clut` operator. When enabled, a second input file must be supplied via the `use` parameter with `"as": "clut"`.

  This operation currently runs via ImageMagick convert stack (not image-resizer daemon), even if `stack: "daemon"` is requested.

  When using multiple inputs, you should provide your primary image as `"as": "base"`. If no explicit `base` alias is set, Transloadit will use the first non-auxiliary input (a file that is not tagged as `watermark` or `clut`) as the primary image.

  The CLUT image acts as a gradient map: each pixel's color channels in the input are replaced with the corresponding color from the CLUT image, based on channel intensity. This is a powerful color grading technique widely used in photography and design workflows.

  Example:

  ```json
  {
    "steps": {
      ":original": {
        "robot": "/upload/handle"
      },
      "lut_image": {
        "robot": "/upload/handle"
      },
      "color_graded": {
        "robot": "/image/resize",
        "use": {
          "steps": [
            { "name": ":original", "as": "base" },
            { "name": "lut_image", "as": "clut" }
          ]
        },
        "clut": true
      }
    }
  }
  ```

* `density`: While in-memory quality and file format depth specifies the color resolution, the density of an image is the spatial (space) resolution of the image. That is the density (in pixels per inch) of an image and defines how far apart (or how big) the individual pixels are. It defines the size of the image in real world terms when displayed on devices or printed.

  You can set this value to a specific `width` or in the format `width`x`height`.

  If your converted image is unsharp, please try increasing density.

* `monochrome`: Transform the image to black and white. This is a shortcut for setting the colorspace to Gray and type to Bilevel.

* `shave`: Shave pixels from the image edges. The value should be in the format `width` or `width`x`height` to specify the number of pixels to remove from each side.
