從零開始用 React 打造原作(青山剛昌)風格全前端圖像生成器

作者: Calpa Liu
字數:2665
出版:2025 年 4 月 28 日

最近,大阪正如火如荼籌備 2025 世界博覽會(EXPO 2025),引發了全日本的話題熱潮。網路上也悄悄流傳起一支以《名偵探柯南》風格打造的非官方宣傳短片,短短幾十秒,卻把大阪街頭、摩天輪與萬博會場場景渲染得充滿懸疑氛圍。這支影片引發了廣大迴響,也讓「只要加上『原作(青山剛昌)』標籤,任何平凡畫面瞬間變推理漫畫現場」這股流行文化再次爆紅。當時我心想,如果也能自己動手做個小工具,會是什麼感覺呢?受此啟發,我開發了這個全前端「原作(青山剛昌)」圖生成器,讓每個人都能輕鬆將自己的照片,變身成充滿故事感的推理場景,無論是街頭一角還是旅途中偶遇的風景,都能瞬間擁有一段懸疑冒險的故事!

成品展示

aoyama-gosho-generator
aoyama-gosho-generator

這個小工具是我自己一點一滴做出來的,靈感來自 2025 大阪世博和最近很紅的名偵探柯南非官方短片。 那時我就在想 —— 如果大家也能輕鬆把自己拍的照片,加上一點推理漫畫的懸疑感,應該很有趣吧?

立即體驗「原作(青山剛昌)」圖生成器,讓你的照片充滿推理氛圍!點擊這裡開始創作

下面這幾張,就是用生成器做出來的範例:

成品樣圖
成品樣圖

成品樣圖
成品樣圖

成品樣圖
成品樣圖

成品樣圖
成品樣圖

這個小工具是免費開放的,而且操作超簡單,只要填幾個欄位,照片馬上變得超有故事感。

使用方法

操作很簡單,我當初就是希望大家不用看教學也能直接上手。只要輸入標題、作者名字、背景圖網址,畫面就會即時更新預覽!滿意後,一鍵就可以直接下載成高畫質的 PNG 圖檔。全程前端處理,不用怕資料外洩或網路慢卡卡,真的就是秒出圖~

立即體驗「原作(青山剛昌)」圖生成器,讓你的照片充滿推理氛圍!點擊這裡開始創作

如果你也對這類前端圖片生成技術有興趣,這篇文章特別適合你。接下來就跟我一起深入了解這套技術吧!

Satori 與全前端圖片生成的優勢解析

為何選擇 Satori?

在眾多圖像生成方案中,Satori 以其極輕量、支援 JSX 與字型嵌入的特性,特別適合全前端即時渲染需求。相較傳統 Puppeteer 截圖或 Serverless 處理,Satori 不需啟動瀏覽器進程,部署與運算成本更低,極大提升了前端開發的自由度與靈活性。

Satori 技術特色與應用場景

Satori 是由 Vercel 開發的輕量級 SVG 生成引擎,專為將 HTML 與 CSS 直接轉譯為 SVG 圖像而設計。它支持 JSX 語法,能夠將 React 元件或「React-like」物件直接渲染為 SVG 字串,並內建字型嵌入、排版、Flexbox 佈局等現代網頁設計特性。這種設計讓 Satori 成為動態生成社交卡片(OG Image)、即時圖像模板等場景的理想選擇。與傳統方案(如 puppeteer 截圖)相比,Satori 不需啟動瀏覽器進程,極大降低運算資源消耗與部署複雜度。

Satori 的一大特點是能夠在瀏覽器端、Node.js 或 Web Worker 等多種環境運行,這讓它非常適合用於全前端架構。其運作邏輯是將 JSX 或 React-like 元件樹解析為 SVG 結構,並根據 inline style 進行渲染。由於 SVG 本身為 XML 格式,易於後續進行 PNG、JPEG 等格式的轉換,進一步擴展了應用場景。

全前端架構的核心價值

全前端架構意指所有圖片生成邏輯皆於瀏覽器端執行,無需依賴任何後端 API 或伺服器資源。這種架構帶來數個顯著優勢。首先,部署與維護成本大幅降低,開發者只需將靜態檔案上傳至 CDN 或靜態網站伺服器即可,無需考慮伺服器擴容、資安維護等問題。其次,圖片生成過程完全在用戶端完成,具備極高的自由度與即時互動性,特別適合個人化工具、社群分享卡片、動態模板等場景。最後,這種架構天生具備水平擴展能力,用戶數量不會對後端造成壓力,且能充分利用現代瀏覽器的計算資源。

以本專案「原作(青山剛昌)」圖生成器為例,用戶可即時調整表單內容與樣式,前端即時生成 SVG,並可一鍵下載 PNG,整個流程無需任何伺服器參與,體現了全前端架構的高效與彈性。

前端動態圖片生成完整流程

元件結構與 Satori 整合方法

Satori 天生支持 JSX 與 React 元件樹作為輸入來源。開發者可將任何純粹、無副作用的 React 元件(即不使用 useState、useEffect 等 Hook)作為 Satori 的渲染對象。Satori 會遞迴解析元件樹,將每個節點的 type、props、style 轉換為對應的 SVG 標籤與屬性。這種設計讓前端開發者能夠沿用既有的 React 組件設計思維,快速構建複雜的圖像模板。

例如,以下是一個典型的 Satori 調用流程:

const svg = await satori(hello, world, {
  width: 600,
  height: 400,
  fonts: [
    {
      name: "Roboto",
      data: robotoArrayBuffer,
      weight: 400,
      style: "normal",
    },
  ],
});

這段程式碼將一個簡單的 React 元件即時渲染為 600x400 的 SVG 字串,並嵌入 Roboto 字型。

非 JSX 與 React-like 結構支援

Satori 也支援不使用 JSX 的寫法,開發者可直接傳入類似 React 元件的物件結構(type、props、children、style),這對於 TypeScript 或非 React 專案尤為重要。例如:

const element = {
  type: "div",
  props: {
    children: "hello, world",
    style: { color: "black", fontSize: "2rem" },
  },
};
const svg = await satori(element, options);

這種寫法讓 Satori 能夠無縫整合至任何 JavaScript/TypeScript 專案。

動態字型與 Emoji 載入技巧

Satori 支援自訂字型嵌入,開發者需於 options.fonts 傳入字型名稱、ArrayBuffer 資料、權重與樣式。若需支援 Emoji,則可透過 loadAdditionalAsset 回調動態載入對應 SVG 資源,並以 base64 形式嵌入。這大幅提升了圖片生成的豐富性與國際化能力。

SVG 輸出與即時互動優勢

由於 Satori 運作於前端,React 元件的任何 props 變動(如表單輸入、顏色選擇等)都可即時重新渲染 SVG,實現毫秒級的互動體驗。這種即時性是傳統伺服器截圖方案難以匹敵的。更進一步,SVG 作為向量圖格式,無論縮放或導出 PNG、JPEG 都能保證畫質不失真,極大提升了用戶體驗。

Satori + React 圖片生成核心實作

Satori 圖片生成核心程式碼

以下為本專案「原作(青山剛昌)」圖生成器的核心代碼片段,體現了 Satori 如何結合 React-like 元件、動態字型與 Emoji 載入,實現即時 SVG 輸出。

// 用 Satori 生成 SVG
const svg = await satori(fn(validatedProps), {
  width: validatedProps.outputWidth,
  height: validatedProps.outputHeight,
  fonts,
  loadAdditionalAsset: async (code: string, segment: string) => {
    if (code === "emoji") {
      const url = `https://api.iconify.design/${emojis[segment]}.svg`;
      const response = await fetch(url);
      const svg = await response.text();
      return `data:image/svg+xml;base64,${Buffer.from(svg).toString("base64")}`;
    }
    return "";
  },
});

這段程式碼說明了幾個重點:

  1. fn(validatedProps) 產生 React-like 元件,作為 Satori 的渲染對象。
  2. validatedProps.outputWidth/Height 動態設定 SVG 尺寸,支援用戶自訂輸出解析度。
  3. fonts 為 ArrayBuffer 格式的字型資料,確保 SVG 文字正確渲染。
  4. loadAdditionalAsset 回調動態載入 Emoji SVG,並以 base64 形式嵌入,提升國際化與視覺豐富度。

圖形內容元件設計實例

圖形內容以純函式元件方式撰寫,兼容 Satori 的渲染規範:

export function AoyamaGosho(props: AoyamaGoshoProps) {
  const { outputWidth, outputHeight, textInputs } = props;
  const { backgroundImage } = textInputs;

  return h("div", { style: { ... } }, [
    h("div", { style: { fontSize: '3rem' } }, "原作"),
    h("div", { style: { fontSize: '4rem' } }, "青山剛昌"),
    h("div", { style: { fontSize: '1rem' } }, "「名探偵コナン」(小学館『週刊少年サンデー』連載中)")
  ]);
}

這裡以 h 函式(React.createElement 替代)組合多層 div,分別設置不同字型大小與內容。所有 style 皆以 inline 形式呈現,符合 Satori 對 CSS 支援的限制(僅支援部分屬性與 inline style)。

SVG 轉 PNG:前端最佳實踐

SVG 生成後,若需導出 PNG,可於前端以 Canvas API 實現。流程為:先將 SVG 字串轉為 base64 資料 URI,然後以 Image 元素載入,最後 drawImage 至 Canvas,再以 toDataURL(“image/png”) 輸出 PNG。以下為簡化版流程:

function svgToPng(svg: string, width: number, height: number): Promise {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => {
      const canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = height;
      const ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, width, height);
      resolve(canvas.toDataURL("image/png"));
    };
    img.src = "data:image/svg+xml;base64," + btoa(svg);
  });
}

這種方式完全於前端執行,無需任何伺服器參與,並可即時將 SVG 轉為高畫質 PNG。

全前端圖片生成的應用場景與未來展望

aoyamagosho-3
aoyamagosho-3

全前端圖片生成的最大優勢在於完全不依賴後端伺服器,開發者只需將靜態檔案部署至 CDN 或靜態網站伺服器,用戶即可於瀏覽器端即時執行所有圖片生成邏輯。這大幅降低了運維與擴展成本,並消除了伺服器擁塞、資安漏洞等潛在風險。由於所有運算皆於用戶端執行,網站流量不會對後端造成壓力,無論同時有多少用戶使用圖片生成器,皆不會影響服務穩定性。

全前端架構賦予開發者極高的設計自由度,用戶可即時預覽所有輸入變動,並根據需求調整模板內容、樣式、解析度等。SVG 作為向量圖格式,無論縮放或導出 PNG、JPEG 都能保證畫質不失真,極大提升了用戶體驗。這種架構特別適合開發各類小型工具、個人媒體、社群分享功能,如動態社交卡片生成器、個人化頭像設計、動態 QR Code 卡片、專屬名片模板等。開發者可根據用戶需求快速調整模板,並即時上線新功能,極大提升開發效率與產品競爭力。

結論

感謝您讓我占用的寶貴時間
感謝您讓我占用的寶貴時間

本篇技術專文以「原作(青山剛昌)」圖生成器為例,完整解析了 Satori + React 全前端圖片生成的技術架構、核心流程與實作細節。這種創新方法不僅展示了前端技術的強大潛力,也為開發者提供了一種高效、靈活的圖像生成解決方案。

隨著瀏覽器運算能力持續提升與前端技術生態日益成熟,全前端圖片生成將成為更多產品與服務的標準方案。開發者可持續關注 Satori 及相關 SVG/Canvas 技術,探索更多創新應用,打造更具互動性與個人化的網頁體驗。這種技術不僅簡化了開發流程,還為用戶提供了更加即時、流暢的圖像生成體驗,為未來的網頁應用開闢了新的可能性。

如果你希望體驗「原作(青山剛昌)」圖生成器,請點擊這裡

想跟上前端開發的最新技術與實戰分享嗎?立即訂閱本站,掌握 React、Vue、TypeScript 等趨勢!
關於 Calpa

Calpa 擅長使用 TypeScriptReact.jsVue.js 建立 Responsive Website。

他積極參與開源社區,曾在 2019 年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在 GitHub 上公開分享個人博客程式碼,已獲得超過 300 顆星星和 60 個分支的支持。

他熱愛學習新技術,並樂意分享經驗。他相信,唯有不斷學習才能跟上快速演變的技術環境。

熱門文章

最新文章