跳到主要内容
知仓学习社ZHICANG

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-compat…

不碰外部(只输出文字)无严重或高危命中sickn33/agentic-awesome-skills

它会碰到什么

扫了多少2 个文本文件,50 KB
它会碰到什么不碰外部(只输出文字)
命中总数4 处
命中统计严重 0 · 高 0 · 中 0 · 低 0

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Photopea Embedded Editor Skill

Detailed Guide

Read [the detailed guide](references/detailed-guide.md) before executing this skill. It retains the complete procedure and reference material. Treat its safety, prerequisites, and validation requirements as mandatory. For focused work, load the relevant sections; for end-to-end work, read the guide completely.

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.


Complete Practical Script Examples

1. Rename all text layers based on their contents

app.preferences.rulerUnits = Units.PIXELS;
var doc = app.activeDocument;

function processLayers(parent) {
  for (var i = 0; i < parent.layers.length; i++) {
    var l = parent.layers[i];
    if (l.typename === "LayerSet") processLayers(l);
    else if (l.kind === LayerKind.TEXT) {
      l.name = l.textItem.contents.substring(0, 30);
    }
  }
}
processLayers(doc);
app.echoToOE("done");

2. Export each layer as a separate PNG

app.preferences.rulerUnits = Units.PIXELS;
var doc = app.activeDocument;

for (var i = 0; i < doc.layers.length; i++) {
  // Hide all layers
  for (var j = 0; j < doc.layers.length; j++) doc.layers[j].visible = false;
  // Show only this layer
  doc.layers[i].visible = true;
  // Export
  var opts = new ExportOptionsSaveForWeb();
  opts.format  = SaveDocumentType.PNG;
  opts.PNG8    = false;
  opts.quality = 100;
  doc.exportDocument(
    new File("/" + doc.layers[i].name + ".png"),
    ExportType.SAVEFORWEB, opts
  );
}

// Restore visibility
for (var i = 0; i < doc.layers.length; i++) doc.layers[i].visible = true;

3. Find and replace text across all text layers

var searchText   = "2024";
var replaceText  = "2025";

function findReplaceText(parent) {
  for (var i = 0; i < parent.layers.length; i++) {
    var l = parent.layers[i];
    if (l.typename === "LayerSet") findReplaceText(l);
    else if (l.kind === LayerKind.TEXT) {
      var t = l.textItem;
      if (t.contents.indexOf(searchText) !== -1) {
        t.contents = t.contents.split(searchText).join(replaceText);
      }
    }
  }
}
findReplaceText(app.activeDocument);
app.echoToOE("Find & Replace complete");

4. Grid of duplicate layers

app.preferences.rulerUnits = Units.PIXELS;
var doc   = app.activeDocument;
var layer = doc.activeLayer;
var cols  = 4, rows = 3;
var padX  = 20, padY = 20;
var w = layer.bounds[2] - layer.bounds[0];
var h = layer.bounds[3] - layer.bounds[1];

for (var r = 0; r < rows; r++) {
  for (var c = 0; c < cols; c++) {
    if (r === 0 && c === 0) continue; // skip original
    var copy = layer.duplicate();
    var targetX = layer.bounds[0] + c * (w + padX);
    var targetY = layer.bounds[1] + r * (h + padY);
    copy.translate(targetX - copy.bounds[0], targetY - copy.bounds[1]);
    copy.opacity = 100 - (r * cols + c) * 5;
  }
}

5. Apply watermark from URL

app.preferences.rulerUnits = Units.PIXELS;
var doc = app.activeDocument;

// Open watermark as smart object layer
app.open("https://example.com/watermark.png", null, true);
var wm = doc.activeLayer;

// Resize to 20% of document width
var wmW = wm.bounds[2] - wm.bounds[0];
var targetW = doc.width * 0.2;
var scalePct = (targetW / wmW) * 100;
wm.resize(scalePct, scalePct, AnchorPosition.TOPLEFT);

// Move to bottom-right with 20px margin
var wmNewW = wm.bounds[2] - wm.bounds[0];
var wmNewH = wm.bounds[3] - wm.bounds[1];
wm.translate(
  doc.width  - wmNewW - 20 - wm.bounds[0],
  doc.height - wmNewH - 20 - wm.bounds[1]
);
wm.opacity = 60;
app.echoToOE("watermark applied");

6. Get all layer info as JSON

function getLayerInfo(parent, depth) {
  depth = depth || 0;
  var result = [];
  for (var i = 0; i < parent.layers.length; i++) {
    var l = parent.layers[i];
    var info = {
      name:    l.name,
      type:    l.typename,
      visible: l.visible,
      opacity: l.opacity,
      depth:   depth
    };
    if (l.typename === "ArtLayer") {
      info.kind   = l.kind.toString();
      info.bounds = [l.bounds[0], l.bounds[1], l.bounds[2], l.bounds[3]];
      if (l.kind === LayerKind.TEXT) {
        info.text = l.textItem.contents;
        info.font = l.textItem.font;
        info.size = l.textItem.size;
      }
    } else if (l.typename === "LayerSet") {
      info.children = getLayerInfo(l, depth + 1);
    }
    result.push(info);
  }
  return result;
}
app.echoToOE(JSON.stringify(getLayerInfo(app.activeDocument)));

Limitations

  • This skill covers host-page integration patterns; it does not replace Photopea's own terms, API documentation, or licensing guidance.
  • Remote URL loading depends on browser CORS behavior, network availability, and the user's Photopea account/session state.
  • runScript executes scripts inside the embedded Photopea document context. Only run scripts you understand and only with user-approved files.
  • Serialize dynamic values with JSON.stringify before embedding them in a runScript string. Never concatenate user-provided URLs, layer names, or text directly into Photopea script source.
  • Export behavior can vary by document size, browser memory limits, and the formats supported by the active Photopea runtime.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

同名技能的其他版本

有 3 个不同仓库或目录里都有叫 photopea-embedded-editor 的技能。它们内容并不相同,别混用: