Working with Images

Image layers allow you to render static .jpg, .png, or .webp files over time. They are incredibly powerful when combined with the layout object for Picture-in-Picture, logos, or watermarks.

Basic Image Object

An image layer needs an asset_id and a time definition. time.start_seconds is required. time.duration_seconds is optional when ReelForge can infer overall composition duration from timed media layers (or explicit composition.duration_seconds).

Duration Inference Precedence

When image time.duration_seconds is omitted, ReelForge resolves timing in this order:

  1. If image time.duration_seconds is provided, that explicit value is used.
  2. Otherwise, if composition.duration_seconds is provided, image duration is inferred as:
    • composition.duration_seconds - image.time.start_seconds
  3. Otherwise, composition duration is inferred from the maximum timed end across composition.timeline and composition.text_overlays, then image duration is inferred from that result.

If none of the above can establish a valid duration, validation fails with a clear error.

If composition.auto_stitch is enabled and media layers are untimed, ReelForge can still infer composition duration at render time by probing media duration, then apply the same image-duration inference.

{
  "id": "watermark-logo",
  "type": "image",
  "asset_id": "asset-logo-1",
  "time": {
    "start_seconds": 0,
    "duration_seconds": 60
  }
}

Spatial Coordinates (layout)

To position an image, supply a layout object. The layout allows you to define standard CSS-like spatial bounds.

  • x: Horizontal position (e.g., "10%", "20px"). Maps to the CSS left property.
  • y: Vertical position (e.g., "10%", "20px"). Maps to the CSS top property.
  • width: The width of the bounding box.
  • height: The height of the bounding box.
  • fit: How the image fits inside its bounding box ("cover" or "contain").
{
  "id": "logo-top-right",
  "type": "image",
  "asset_id": "asset-logo-1",
  "layout": {
    "x": "80%",
    "y": "5%",
    "width": "15%",
    "height": "10%",
    "fit": "contain"
  }
}

Background Mode (background_mode)

Similar to Videos, images support background_mode. If your image does not perfectly match its layout bounding box, you can control the empty space.

For things like transparent .png logos, you should always explicitly set "background_mode": "transparent", otherwise they will render with a blurred background copy of themselves.

{
  "id": "transparent-logo",
  "type": "image",
  "asset_id": "asset-logo-1",
  "background_mode": "transparent",
  "layout": {
    "x": "10px",
    "y": "10px",
    "width": "100px",
    "height": "100px",
    "fit": "contain"
  }
}

Styling Images

The style object uses snake_case keys (consistent with the rest of the manifest):

  • opacity (number, 0–1)
  • border_radius (string, e.g. "24px")
  • box_shadow (string, e.g. "0 10px 30px rgba(0,0,0,0.5)")
{
  "id": "styled-image",
  "type": "image",
  "asset_id": "asset-pic",
  "style": {
    "opacity": 0.8,
    "border_radius": "24px",
    "box_shadow": "0 10px 30px rgba(0,0,0,0.5)"
  }
}

The Full Image Request Example

This example places a transparent PNG logo in the top right corner of the video for the entire 10-second duration.

curl -X POST https://api.reelforger.com/v1/videos/render \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "v1",
    "output": {
      "width": 1080,
      "height": 1920,
      "fps": 30
    },
    "assets": [
        {
          "id": "asset-bg-video",
          "type": "video",
          "url": "https://example.com/background.mp4"
        },
        {
          "id": "asset-logo",
          "type": "image",
          "url": "https://example.com/logo.png"
        }
    ],
    "composition": {
        "timeline": [
          {
            "id": "base-video",
            "type": "video",
            "asset_id": "asset-bg-video",
            "time": {
              "start_seconds": 0,
              "duration_seconds": 10
            }
          },
          {
            "id": "overlay-logo",
            "type": "image",
            "asset_id": "asset-logo",
            "background_mode": "transparent",
            "time": {
              "start_seconds": 0,
              "duration_seconds": 10
            },
            "layout": {
              "x": "80%",
              "y": "5%",
              "width": "15%",
              "height": "10%",
              "fit": "contain",
              "z_index": 10
            }
          }
        ]
    }
  }'