Files
AgentCompany/builtin-skills/Video-maker/remotion-best-practices/rules/images.md
T
ZacharyZhang-NY e74dafcd36 Silence render-disposed spam, unbreak bundled skills, drop board wake
Three independently ugly bugs that all fed the same log flood:

* Electron's `WebFrameMain.send` writes every "Render frame was disposed"
  to stderr via `console.error`. When the worker fans a second
  agent-event past a reloading renderer, we produced thousands of
  identical lines and stalled the main loop on stderr I/O. Added a
  `mainFrame.detached` guard so the send is short-circuited before
  Electron's own catch block fires, and installed a targeted filter in
  `suppress-warnings.ts` (now actually imported from the entry point)
  so the specific `console.error("Error sending from webFrameMain:"…)`
  noise never reaches the terminal. Any other payload still surfaces.

* `dispatchAgentMessage` accepted the human-reader sentinel as a wake
  target when an agent replied to `__board__` — `wakeAgentIfPossible`
  then called `db.getAgent("__board__")`, threw, and the dispatcher
  kept repeating on every send. Strip `HUMAN_SENDER_ID` at
  `resolveMessageWakeTargets`, and keep a defense-in-depth guard in the
  heartbeat so a stray caller (future automation fan-out) cannot
  reintroduce the crash.

* Pi's skills loader rejects any SKILL.md whose frontmatter `name`
  diverges from its parent directory. The four bundled `my-writing-style`
  copies declared `name: writing-style-skill`, so every install emitted
  a warning and dropped the skill. They also lived as orphan gitlinks
  (mode 160000 without .gitmodules), and the global `*.md` gitignore
  hid every other SKILL.md from version control. Fixed the frontmatter
  to match the dir, converted the dangling submodules to plain trees,
  and allowlisted `builtin-skills/**/*.md` so a fresh clone carries the
  catalogue instead of silently losing it.
2026-04-20 08:13:48 -04:00

2.7 KiB

name, description, metadata
name description metadata
images Embedding images in Remotion using the <Img> component
tags
images, img, staticFile, png, jpg, svg, webp

Using images in Remotion

The <Img> component

Always use the <Img> component from remotion to display images:

import { Img, staticFile } from "remotion";

export const MyComposition = () => {
  return <Img src={staticFile("photo.png")} />;
};

Important restrictions

You MUST use the <Img> component from remotion. Do not use:

  • Native HTML <img> elements
  • Next.js <Image> component
  • CSS background-image

The <Img> component ensures images are fully loaded before rendering, preventing flickering and blank frames during video export.

Local images with staticFile()

Place images in the public/ folder and use staticFile() to reference them:

my-video/
├─ public/
│  ├─ logo.png
│  ├─ avatar.jpg
│  └─ icon.svg
├─ src/
├─ package.json
import { Img, staticFile } from "remotion";

<Img src={staticFile("logo.png")} />;

Remote images

Remote URLs can be used directly without staticFile():

<Img src="https://example.com/image.png" />

Ensure remote images have CORS enabled.

For animated GIFs, use the <Gif> component from @remotion/gif instead.

Sizing and positioning

Use the style prop to control size and position:

<Img
  src={staticFile("photo.png")}
  style={{
    width: 500,
    height: 300,
    position: "absolute",
    top: 100,
    left: 50,
    objectFit: "cover",
  }}
/>

Dynamic image paths

Use template literals for dynamic file references:

import { Img, staticFile, useCurrentFrame } from "remotion";

const frame = useCurrentFrame();

// Image sequence
<Img src={staticFile(`frames/frame${frame}.png`)} />

// Selecting based on props
<Img src={staticFile(`avatars/${props.userId}.png`)} />

// Conditional images
<Img src={staticFile(`icons/${isActive ? "active" : "inactive"}.svg`)} />

This pattern is useful for:

  • Image sequences (frame-by-frame animations)
  • User-specific avatars or profile images
  • Theme-based icons
  • State-dependent graphics

Getting image dimensions

Use getImageDimensions() to get the dimensions of an image:

import { getImageDimensions, staticFile } from "remotion";

const { width, height } = await getImageDimensions(staticFile("photo.png"));

This is useful for calculating aspect ratios or sizing compositions:

import {
  getImageDimensions,
  staticFile,
  CalculateMetadataFunction,
} from "remotion";

const calculateMetadata: CalculateMetadataFunction = async () => {
  const { width, height } = await getImageDimensions(staticFile("photo.png"));
  return {
    width,
    height,
  };
};