Remotion LabRemotion Lab
視覺設計<Img> 元件

<Img> 元件

使用 <Img> 元件在 Remotion 中顯示圖片,確保圖片在渲染時完整載入,避免渲染閃爍問題。

什麼是 <Img>

<Img> 標籤的用法與普通的 <img> HTML 標籤相同,但有一個關鍵優勢:若使用 <Img>,Remotion 會確保圖片在渲染該幀之前完整載入。 這樣可以避免圖片在渲染時尚未載入完成所造成的閃爍(flickering)問題。

API

src

將圖片放入 public/ 資料夾,並使用 staticFile() 來參照它。

使用本地靜態檔案:

import { AbsoluteFill, Img, staticFile } from "remotion";
 
export const MyComp: React.FC = () => {
  return (
    <AbsoluteFill>
      <Img src={staticFile("hi.png")} />
    </AbsoluteFill>
  );
};

使用遠端圖片:

import { AbsoluteFill, Img } from "remotion";
 
export const MyComp: React.FC = () => {
  return (
    <AbsoluteFill>
      <Img src={"https://picsum.photos/200/300"} />
    </AbsoluteFill>
  );
};

onError

為了以更健壯的方式使用 <Img> 標籤,你應該處理圖片無法載入時發生的錯誤:

import { AbsoluteFill, Img, staticFile } from "remotion";
 
export const MyComp: React.FC = () => {
  return (
    <AbsoluteFill>
      <Img
        src={staticFile("hi.png")}
        onError={(event) => {
          // 在此處理圖片載入錯誤
          console.error("圖片載入失敗", event);
        }}
      />
    </AbsoluteFill>
  );
};

重要:若發生錯誤,必須卸載該元件或替換 src,否則渲染將會逾時。從 v3.3.82 起,圖片載入失敗後會先重試,重試失敗後才觸發 onError

maxRetries v3.3.82

若圖片載入失敗,從 v3.3.82 起會自動重試。預設值為 2

重試使用指數退避策略:

  • 第一次與第二次嘗試之間延遲 1000ms
  • 然後是 2000ms
  • 然後是 4000ms
  • 以此類推

pauseWhenLoading? v4.0.111

若設為 true,在圖片載入時暫停 Player。請參閱:緩衝狀態

delayRenderTimeoutInMilliseconds? v4.0.140

自訂此元件進行的 delayRender() 呼叫的逾時時間(毫秒)。

delayRenderRetries? v4.0.140

自訂此元件進行的 delayRender() 呼叫的重試次數。建議優先使用 maxRetries prop,而非此 prop。

其他 Props

<Img> 繼承了普通 <img> 標籤的所有 props,例如 styleclassNamealt 等。

錯誤行為

  • 從 v4.0.0 起:若圖片載入失敗且沒有剩餘重試次數,則會呼叫 cancelRender 拋出錯誤,除非你使用 onError() 處理錯誤。
  • 從 v3.3.82 起:若圖片載入失敗,會最多重試兩次。
  • 更早的版本:載入圖片失敗會導致 console 中出現錯誤訊息,並最終逾時。

GIF 動畫

不要使用 <Img> 標籤來顯示 GIF。請改用 @remotion/gif 套件:

import { Gif } from "@remotion/gif";
import { staticFile } from "remotion";
 
export const MyComp: React.FC = () => {
  return (
    <Gif
      src={staticFile("animation.gif")}
      width={400}
      height={300}
      fit="fill"
    />
  );
};

限制

Chrome 可顯示的最大解析度為 2^29 像素(5.39 億像素)。Remotion 繼承了此限制。

進階應用範例

帶動畫效果的圖片

搭配 interpolateuseCurrentFrame 製作圖片動畫:

import { AbsoluteFill, Img, staticFile, interpolate, useCurrentFrame } from "remotion";
 
export const AnimatedImage: React.FC = () => {
  const frame = useCurrentFrame();
 
  const opacity = interpolate(frame, [0, 30], [0, 1], {
    extrapolateRight: "clamp",
  });
 
  const scale = interpolate(frame, [0, 30], [0.8, 1], {
    extrapolateRight: "clamp",
  });
 
  return (
    <AbsoluteFill
      style={{ justifyContent: "center", alignItems: "center" }}
    >
      <Img
        src={staticFile("logo.png")}
        style={{
          opacity,
          transform: `scale(${scale})`,
          width: 400,
          height: 400,
          objectFit: "contain",
        }}
      />
    </AbsoluteFill>
  );
};

多張圖片的輪播效果

import { AbsoluteFill, Img, staticFile, Sequence } from "remotion";
 
const images = ["slide1.png", "slide2.png", "slide3.png"];
const SLIDE_DURATION = 60; // 每張幻燈片顯示 2 秒(30fps)
 
export const Slideshow: React.FC = () => {
  return (
    <AbsoluteFill>
      {images.map((image, index) => (
        <Sequence
          key={image}
          from={index * SLIDE_DURATION}
          durationInFrames={SLIDE_DURATION}
        >
          <AbsoluteFill>
            <Img
              src={staticFile(image)}
              style={{ width: "100%", height: "100%", objectFit: "cover" }}
              onError={() => console.error(`Failed to load ${image}`)}
            />
          </AbsoluteFill>
        </Sequence>
      ))}
    </AbsoluteFill>
  );
};

帶有錯誤處理的容錯圖片元件

import { AbsoluteFill, Img, staticFile } from "remotion";
import { useState } from "react";
 
interface ResilientImageProps {
  src: string;
  fallbackSrc?: string;
}
 
export const ResilientImage: React.FC<ResilientImageProps> = ({
  src,
  fallbackSrc,
}) => {
  const [currentSrc, setCurrentSrc] = useState(src);
  const [failed, setFailed] = useState(false);
 
  if (failed) {
    return (
      <div
        style={{
          width: "100%",
          height: "100%",
          backgroundColor: "#333",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          color: "white",
        }}
      >
        圖片載入失敗
      </div>
    );
  }
 
  return (
    <Img
      src={currentSrc}
      onError={() => {
        if (fallbackSrc && currentSrc !== fallbackSrc) {
          setCurrentSrc(fallbackSrc);
        } else {
          setFailed(true);
        }
      }}
      style={{ width: "100%", height: "100%", objectFit: "cover" }}
    />
  );
};

相容性

環境支援
Chrome
Firefox
Safari
客戶端渲染
伺服器端渲染
Player
Studio

相關資源