Skip to main content

photopea-embedded-editor

Embed Photopea in web apps using photopea.js. Covers embedding, file I/O, scripting, exporting, layers, text, filters, and the full Photoshop-compatible API.

インストールへ移動

ソース情報

リポジトリ
AlperTuncOrtak/crypto-data-pipeline
ソースの最終更新活動
2026年6月3日 12:03
検出された SKILL.md の言語
英語
スター
2
フォーク
0

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
photopea-embedded-editor
description
Embed Photopea in web apps using photopea.js. Covers embedding, file I/O, scripting, exporting, layers, text, filters, and the full Photoshop-compatible API.
risk
safe
source
community
source_repo
yikuansun/PhotopeaAPI
source_type
community
license
MIT
license_source
https://github.com/yikuansun/PhotopeaAPI/blob/master/LICENSE
date_added
2026-05-20T00:00:00.000Z
# Photopea Embedded Editor Skill ## Using photopea.js (yikuansun/PhotopeaAPI) in Websites & Apps --- ## When to Use This Skill Use this skill for **every task** that involves: - Embedding Photopea as an image editor inside a webpage or web app - Controlling an embedded Photopea instance from your JavaScript code - Automating image editing workflows from a host page (open files, run scripts, export results) - Building an image editing feature into your product using Photopea as the engine - Writing scripts to manipulate documents, layers, text, selections, filters, colors, and paths **Do NOT** use raw `postMessage` wiring — always use `photopea.js` as the wrapper. --- ## Library: photopea.js `photopea.js` is a Promises-based JavaScript wrapper around the Photopea Live Messaging API. Repository: https://github.com/yikuansun/PhotopeaAPI npm package: https://www.npmjs.com/package/photopea ### Installation **CDN (no build step)** ```html <script src="https://cdn.jsdelivr.net/npm/photopea@1.1.1/dist/photopea.min.js"></script> ``` **Self-hosted** ```html <script src="./photopea.min.js"></script> ``` **npm (Webpack / Vite / Rollup)** ```bash npm install photopea ``` ```js import Photopea from "photopea"; ``` --- ## Core API: The `Photopea` Class | Method | Description | |--------|-------------| | `Photopea.createEmbed(container)` | Creates + injects the iframe, resolves when ready | | `new Photopea(window.parent)` | Plugin mode: wrap the parent window | | `pea.runScript(script)` | Run JS string inside Photopea; returns output array | | `pea.loadAsset(arrayBuffer)` | Load binary file (image, font, brush, etc.) | | `pea.openFromURL(url, asSmart)` | Open remote URL as new doc or smart object layer | | `pea.exportImage(type)` | Export current doc; returns `Blob` (`"png"` or `"jpg"`) | All methods return Promises — always `await` or `.then()`. --- ## Step 1 — Embed The container `<div>` **must** have a fixed width and height before calling `createEmbed`. ```html <div id="editor" style="width:1000px; height:650px;"></div> <script src="https://cdn.jsdelivr.net/npm/photopea@1.1.1/dist/photopea.min.js"></script> <script> Photopea.createEmbed(document.getElementById("editor")).then(async (pea) => { // pea is ready }); </script> ``` **React:** ```jsx import { useEffect, useRef } from "react"; import Photopea from "photopea"; export default function Editor() { const containerRef = useRef(null); const peaRef = useRef(null); useEffect(() => { if (!containerRef.current || peaRef.current) return; Photopea.createEmbed(containerRef.current).then((pea) => { peaRef.current = pea; }); }, []); return <div ref={containerRef} style={{ width: "100%", height: "650px" }} />; } ``` --- ## Step 2 — Opening Files ```js // Remote URL → new document await pea.openFromURL("https://example.com/design.psd", false); // Remote URL → smart object layer inside current document await pea.openFromURL("https://example.com/overlay.png", true); // Local file (user input → ArrayBuffer → loadAsset) document.getElementById("fileInput").addEventListener("change", async (e) => { const buf = await e.target.files[0].arrayBuffer(); await pea.loadAsset(buf); }); // Base64 data URI via runScript await pea.runScript(`app.open("data:image/png;base64,iVBORw0...");`); ``` --- ## Step 3 — Running Scripts `runScript` sends a JS string, returns an array of `app.echoToOE(...)` values + `"done"` last. ```js const result = await pea.runScript(`app.echoToOE("hello");`); // result → ["hello", "done"] // Return structured data const out = await pea.runScript(` app.echoToOE(JSON.stringify({ width: app.activeDocument.width, height: app.activeDocument.height, layers: app.activeDocument.layers.length })); `); const info = JSON.parse(out[0]); ``` --- ## Step 4 — Exporting ```js // PNG Blob (via exportImage) const blob = await pea.exportImage("png"); document.getElementById("preview").src = URL.createObjectURL(blob); // JPEG Blob const blob = await pea.exportImage("jpg"); // WebP / PSD / quality-controlled JPEG via saveToOE const result = await pea.runScript(`app.activeDocument.saveToOE("webp:0.85");`); const webpBlob = new Blob([result[0]], { type: "image/webp" }); const result = await pea.runScript(`app.activeDocument.saveToOE("psd:true");`); const psdBlob = new Blob([result[0]], { type: "application/octet-stream" }); // Trigger download async function download(pea, filename = "export.png") { const blob = await pea.exportImage("png"); const a = Object.assign(document.createElement("a"), { href: URL.createObjectURL(blob), download: filename }); a.click(); } ``` **Export format strings for `saveToOE`:** | String | Format | |--------|--------| | `"png"` | PNG lossless | | `"jpg"` | JPEG default | | `"jpg:0.8"` | JPEG quality 0.0–1.0 | | `"webp:0.7"` | WebP quality 0.0–1.0 | | `"psd"` | Full PSD | | `"psd:true"` | Minified PSD | | `"svg:true"` | SVG | --- ## Step 5 — Loading Assets ```js // Font const buf = await (await fetch("https://example.com/MyFont.otf")).arrayBuffer(); await pea.loadAsset(buf); // Now usable in textItem.font // Brush await pea.loadAsset(await (await fetch("Nature.ABR")).arrayBuffer()); // Gradient await pea.loadAsset(await (await fetch("Gradients.GRD")).arrayBuffer()); ``` --- ## Step 6 — Plugin Mode ```js // Your page is inside Photopea's sidebar iframe const pea = new Photopea(window.parent); const out = await pea.runScript(`app.echoToOE(app.activeDocument.width);`); console.log("Width:", out[0]); // Load an asset from your plugin const buf = await (await fetch("https://my-assets.com/sticker.png")).arrayBuffer(); await pea.loadAsset(buf); ``` Plugin config: ```json { "environment": { "plugins": [{ "name": "My Plugin", "url": "https://my-plugin.example.com", "icon": "===https://my-plugin.example.com/icon.png" }] } } ``` --- ## Utility Patterns ### addImageAndWait — robust async layer insertion ```js async function addImageAndWait(pea, imgURI) { let count = "done"; while (count === "done") count = (await pea.runScript(`app.echoToOE(app.activeDocument.layers.length)`))[0]; count = parseInt(count); await pea.runScript(`app.open("${imgURI}", null, true);`); return new Promise((resolve) => { const check = async () => { const n = parseInt((await pea.runScript( `app.echoToOE(app.activeDocument.layers.length)` ))[0]); n === count + 1 ? resolve() : setTimeout(check, 50); }; check(); }); } ``` ### getDocumentAsImage — returns `<img>` element ```js async function getDocumentAsImage(pea) { const result = await pea.runScript(`app.activeDocument.saveToOE('png')`); return new Promise((resolve) => { const fr = new FileReader(); fr.addEventListener("load", (e) => { const img = new Image(); img.src = e.target.result; resolve(img); }); fr.readAsDataURL(new Blob([result[0]], { type: "image/png" })); }); } ``` --- ## Real-World Patterns ### Pattern A — Open + Export UI ```html <input type="file" id="fileInput" accept="image/*,.psd"> <button id="exportBtn">Export PNG</button> <div id="editor" style="width:100%;height:600px;"></div> <script src="https://cdn.jsdelivr.net/npm/photopea@1.1.1/dist/photopea.min.js"></script> <script> let pea; Photopea.createEmbed(document.getElementById("editor")).then(p => pea = p); document.getElementById("fileInput").addEventListener("change", async e => { await pea.loadAsset(await e.target.files[0].arrayBuffer()); }); document.getElementById("exportBtn").addEventListener("click", async () => { const blob = await pea.exportImage("png"); const a = Object.assign(document.createElement("a"), { href: URL.createObjectURL(blob), download: "export.png" }); a.click(); }); </script> ``` ### Pattern B — Template + Text Edit + Export ```js async function generateCard(pea, name, tagline) { await pea.openFromURL("https://example.com/card.psd", false); await pea.runScript(` app.activeDocument.layers.getByName("Name").textItem.contents = "${name}"; app.activeDocument.layers.getByName("Tagline").textItem.contents = "${tagline}"; `); return await pea.exportImage("png"); } ``` ### Pattern C — Batch Watermark ```js async function batchWatermark(pea, imageURLs, watermarkURL) { const results = []; for (const url of imageURLs) { await pea.openFromURL(url, false); await pea.openFromURL(watermarkURL, true); await pea.runScript(` var doc = app.activeDocument, wm = doc.activeLayer; wm.translate(doc.width - wm.bounds[2] - 20, doc.height - wm.bounds[3] - 20); wm.opacity = 70; `); results.push(await pea.exportImage("png")); await pea.runScript(`app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);`); } return results; } ``` --- # FULL SCRIPTING API REFERENCE > All code in this section runs **inside `pea.runScript("...")`** strings. > Photopea implements the Adobe Photoshop CC 2015 JavaScript scripting interface. > Any Photoshop script targeting that version should work in Photopea. --- ## `app` — Application Object ### Properties | Property | Type | R/W | Description |
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る