me:DERU is an extensible multi-EFX engine with two processing modes — pick the one that fits your workflow.
me:DERU は拡張型マルチEFXエンジンです。2つの方式で画像を加工できます。
| Modeモード | Styleスタイル |
| 🎨 | DERU | Layer-based compositing — linear, intuitiveレイヤー合成 — 直線的、直感的 |
| 🧩 | NODE | Node graph pipeline — flexible, powerfulノードグラフ — 自由度が高い、強力 |
📐 me:DERU Architecture📐 me:DERU アーキテクチャ
flowchart LR
DRAW["✏️ DRAW\n(velvet.html)"] -->|📸 Snapshot| LIB["📸 LIBRARY\n(IndexedDB)"]
subgraph MEDERU["🔮 me:DERU"]
DERU["🎨 DERU\nLayer Compositing"]
NODE["🧩 NODE\nGraph Pipeline"]
end
LIB -->|"Select image"| DERU
LIB -->|"Select / L key"| NODE
DERU <-->|"Shared LIBRARY"| NODE
DERU -->|Export| POST["📮 POST\nMint / Share"]
NODE -->|"S key / Output"| POST
me:DERU is the extensible multi-EFX engine within mederu Atelier. It offers two modes — DERU for intuitive layer-based compositing, and NODE for flexible graph-based pipelines. Both share the same LIBRARY and EFX modules, which are fully plugin-based.me:DERU は mederu Atelier の拡張型マルチEFXエンジンです。DERU(直感的なレイヤー合成)と NODE(自由度の高いグラフパイプライン)の2つのモードを提供します。LIBRARYとEFXモジュールは共通で、プラグイン方式で拡張可能です。
🎨 DERU Mode — Layer Compositing🎨 DERU モード — レイヤー合成
DERU mode is a layer-based image compositing engine. Stack multiple images as layers, apply EFX chains to each, and composite them together.DERU モードはレイヤーベースの画像合成エンジンです。複数の画像をレイヤーとして重ね、各レイヤーに EFX チェーンを適用して合成します。
flowchart TD
A["📸 Select from LIBRARY"] --> B["📚 Add as Layer"]
B --> C["🎛️ Add EFX Chain"]
C --> D["Adjust Parameters"]
D --> E["🔄 Real-time Preview"]
E --> F{"Satisfied?"}
F -->|No| C
F -->|Yes| G["📤 Export → POST"]
Mode Tabsモード切替
| Tab | Description説明 |
| 🎛️ LAYERS | Layer compositing mode — stack images and apply EFXレイヤー合成モード。画像を重ねてEFX適用 |
| 🎞️ GIF | GIF animation creation modeGIFアニメーション作成モード |
⌨️ DERU Keyboard Shortcuts⌨️ DERU キーボードショートカット
| Keyキー | Action機能 |
| H | Toggle help panelヘルプパネル 表示/非表示 |
| Space | [GIF] Play / Pause animation[GIF] 再生/一時停止 |
| Delete / ⌫ | [GIF] Remove current frame[GIF] 現在のフレーム削除 |
| Escape | Close help / modalsヘルプ/モーダルを閉じる |
📚 LAYERS Section📚 LAYERS セクション
| Action操作 | Method方法 |
| Add layerレイヤー追加 | Click LIBRARY thumbnail or ➕ Add LayerLIBRARY の画像クリック or ➕ Add Layer |
| Select layerレイヤー選択 | Click layer rowレイヤー行をクリック |
| Show / Hide表示/非表示 | 👁️ / 🚫 |
| Delete layerレイヤー削除 | 🗑️ Delete Layer |
| Collapse sectionセクション折りたたみ | Click section titleセクションタイトルクリック |
Layer Orderレイヤー表示順序
- Top of list = frontmost (Photoshop-style)リスト上部 = 最前面(Photoshop 式)
- New layers are always added at the top新規レイヤーは常に最上位に追加
Layer Parametersレイヤーパラメータ
| Parameterパラメータ | Description説明 |
| Opacity | 0–100% |
| Blend Mode | normal · multiply · screen · overlay · difference · color-dodge · color-burn · hard-light · soft-light |
📸 LIBRARY Section📸 LIBRARY セクション
| Action操作 | Method方法 |
| Add as layerレイヤーとして追加 | Click thumbnailサムネイルクリック |
| Delete individual個別削除 | Hover → ✕ buttonサムネイルにホバー → ✕ |
| Clear all全削除 | 🗑️ Clear All (shown when 2+ frames)🗑️ Clear All (2個以上で表示) |
| Import images画像インポート | 📁 Import |
| Collapse折りたたみ | Click titleタイトルクリック |
🎛️ EFX Chain🎛️ EFX チェーン
Apply effects as a chain to the selected layer. Effects are processed in order.選択中のレイヤーに対してエフェクトをチェーン(連鎖)で適用できます。
flowchart LR
SRC["Source Image"] --> E1["EFX 1\nColor Adjust"]
E1 --> E2["EFX 2\nMelt"]
E2 --> E3["EFX 3\nNoise"]
E3 --> OUT["Output"]
| Action操作 | Method方法 |
| Add EFXEFX 追加 | ➕ Add Effect |
| Remove EFXEFX 削除 | ✕ |
| Toggle ON/OFFEFX ON/OFF | Click EFX nameEFX名クリック |
🎞️ GIF Mode🎞️ GIF モード
| Action操作 | Method方法 |
| Select framesフレーム選択 | Click LIBRARY thumbnails (checkmark)LIBRARYのサムネイルをクリック |
| Add to timelineタイムラインに追加 | ➕ Add Selected |
| Frame delayフレーム遅延 | Delay slider per frame各フレームの delay スライダー |
| Play direction再生方向 | forward / reverse / pingpong |
🌊 Auto-Motion Presets🌊 Auto-Motion プリセット
Generate GIF animations from a single image automatically:単一画像からGIFアニメーションを自動生成:
| Presetプリセット | Icon | Description説明 |
| Wave H | 🌊 | Horizontal wave distortion水平方向の波形変形 |
| Wave V | 🌊 | Vertical wave distortion垂直方向の波形変形 |
| Squishy | 🫠 | Squish & stretch bounce伸び縮みバウンス |
| 3D Spin | 🔄 | Pseudo-3D card flip疑似3Dカード回転 |
| Spiral | 🌀 | Rotate + scale spiral回転+スケールスパイラル |
| Bounce | ⬆ | Vertical bouncing垂直バウンス |
| Trail | 👻 | Ghost trail effectゴーストトレイル |
| Pulse | 💫 | Pulsing scale脈動スケール |
Parameters: Amplitude (strength), Frequency (cycles), Speedパラメータ: Amplitude(強度), Frequency(サイクル数), Speed(速度)
🧩 NODE Mode — Graph Pipeline🧩 NODE モード — グラフパイプライン
NODE mode is a node-graph-based image processing pipeline. Connect nodes with wires to build your processing flow.NODE モードはノードグラフベースの画像処理パイプラインです。ノード同士を線で繋いで処理フローを構築します。
flowchart TD
A["Tab / A to open palette"] --> B["Add nodes"]
B --> C["Connect ports with wires"]
C --> D["Load image: D&D / click / L key"]
D --> E["Adjust parameters"]
E --> F{"Auto mode?"}
F -->|Yes| G["🔄 Auto-execute\n600ms debounce"]
F -->|No| H["E / Enter to execute"]
G --> I["Preview updates"]
H --> I
I --> J["S to send to POST"]
⌨️ NODE Keyboard Shortcuts⌨️ NODE キーボードショートカット
※ Case-insensitive — works with CapsLock ON※ 大文字・小文字どちらでも動作します (CapsLock OK)
| Keyキー | Action機能 |
| H | Toggle help panelヘルプパネル 表示/非表示 |
| Tab / A | Toggle Add Node paletteAdd Node パレット 表示/非表示 |
| L | Toggle LIBRARY popup (select Source image)LIBRARY ポップアップ(Source画像選択) |
| E / Enter | Execute graph pipelineグラフ実行 |
| S | Save — export output to POSTSave — 出力画像を POST に送る |
| Delete / ⌫ | Delete selected node or edge選択中のノード/エッジを削除 |
| Escape | Close all panels / deselect全パネルを閉じる / 選択解除 |
| F | Fit view (zoom to show all nodes)ビューをフィット |
🖱️ Mouse Controls🖱️ マウス操作
| Action操作 | Method方法 |
| Move nodeノード移動 | Drag nodeノードをドラッグ |
| Connect接続 | Drag port ● → port ●ポート●からポート●へドラッグ |
| Select edgeエッジ選択 | Click wire線をクリック |
| Load image画像読込 | D&D / click Source / L for LIBRARYD&D / クリック / L でLIBRARY |
| Zoomズーム | Mouse wheelマウスホイール |
| Panパン | Drag background背景をドラッグ |
| Zoom previewプレビュー拡大 | Click EFX node preview imageEFXノードのプレビュー画像をクリック |
📦 Node Types📦 ノードタイプ
flowchart LR
subgraph UTILITY["🔧 UTILITY"]
SRC["🖼️ Source\nImage Input"]
BLD["🔀 Blend\nCompositing"]
OUT["📤 Output\nFinal Result"]
end
subgraph EFX["🎛️ EFX"]
FLT["🟣 Filter"]
DST["🔵 Distortion"]
GEN["🟡 Generative"]
end
SRC --> FLT --> DST --> OUT
SRC --> BLD --> OUT
| Node | Color色 | Description説明 |
| 🖼️ Source | 🟢 | Image input — D&D, click, or L key画像入力。D&D / クリック / L でLIBRARY |
| 🔀 Blend | 🟠 | Mix 2 inputs (multiply, screen, overlay…)2つの入力を合成 |
| 📤 Output | 🔴 | Final output — ⛶ fullscreen preview最終出力先。⛶ で全画面プレビュー |
🎛️ EFX Module Catalog🎛️ EFX モジュール一覧
🟣 FILTER 11
| Module | Icon | Parameters | Description説明 |
| Color Adjust | 🎨 | Brightness, Contrast, Saturation | Color correction色調補正 |
| Invert | 🔄 | — | Color inversion (negative)色反転(ネガ) |
| Posterize | 🖼️ | Levels | Posterizationポスタリゼーション |
| Threshold | ⚫ | Level | Black & white binarize白黒二値化 |
| Duotone | 🎭 | Shadow, Highlight | Dual-tone mappingダブルトーン |
| Gradient Map | 🌈 | Shadow, Mid, Highlight | Gradient mapグラデーションマップ |
| Lo-Fi | 📼 | Pixelate, Noise, Scanlines | Retro / VHS effectレトロ風加工 |
| Color Shift | 🎨 | Intensity | Random hue shiftランダム色相シフト |
| Line Art | ✏️ | Threshold, Thickness | Line extraction線画抽出 |
| ASCII Art | 🔤 | Size, Density | ASCII art conversionASCIIアート変換 |
| Line Edge | ✍️ | Threshold | Edge detectionエッジ検出 |
🔵 DISTORTION 9
| Module | Icon | Parameters | Description説明 |
| Melt | 🫠 | Intensity, Direction, Drip | Melt / dissolveメルト(溶解) |
| Transform | 🔄 | Scale, Rotate, X, Y | Scale / rotate / translate変形 |
| Feedback | ♾️ | Intensity, Zoom, Rotate | Feedback loopフィードバック |
| RGB Split | 🔴🟢🔵 | Red X/Y, Blue X/Y | RGB channel separationRGBチャンネル分離 |
| RGB Glitch | 🌈 | Intensity | Simple RGB glitch簡易RGBグリッチ |
| Slit Scan | 📊 | Intensity | Slit scanスリットスキャン |
| Portrait Distort | 📐 | Intensity, SliceWidth, Freq | Vertical slice distortion縦スライス歪み |
| Horizontal Distort | 📏 | Intensity, SliceHeight, Freq | Horizontal slice distortion横スライス歪み |
| Fragment Glitch | 💥 | Intensity, BlockSize, Randomness | Fragment glitchフラグメントグリッチ |
🟡 GENERATIVE 1
| Module | Icon | Parameters | Description説明 |
| Noise | 📺 | Level | Add noiseノイズ付加 |
🔄 Auto / Manual Mode🔄 Auto / Manual モード
| Modeモード | Buttonボタン | Behavior動作 |
| Auto | 🔄 Auto | Auto-execute 600ms after parameter changeパラメータ変更後 600ms で自動実行 |
| Manual | ⏸ Manual | Press E / Enter to execute manuallyE / Enter キーで手動実行 |
For heavy effect chains, switch to Manual and execute once after adjusting all parameters.重いエフェクトチェーンでは Manual に切り替えて、調整完了後に一括実行すると効率的です。
📊 Execution Pipeline📊 実行パイプライン
flowchart TD
subgraph Pipeline["Execution Pipeline"]
direction TB
S1["🖼️ Source 1"] --> E1["🎨 Color Adjust"]
E1 --> E2["🫠 Melt"]
S2["🖼️ Source 2"] --> BL["🔀 Blend"]
E2 --> BL
BL --> E3["📺 Noise"]
E3 --> OUT["📤 Output"]
end
Source node previews always show the original image (never overwritten by processing results). EFX / Blend / Output nodes show their processed result. Click any EFX preview to view full-size.Source ノードのプレビューは常に元画像を表示。EFX / Blend / Output は処理結果を表示。EFXのプレビューをクリックでフルサイズ表示。
🔧 DERU vs NODE🔧 DERU vs NODE の使い分け
| 🎨 me:DERU | 🧩 NODE |
| Workflow操作感 | Linear (top → down)直線的 | Free graph (node wiring)自由グラフ |
| Layersレイヤー | ✅ | ✅ via Blend node✅ Blendノードで |
| EFX ChainEFXチェーン | Per-layer chainレイヤーごと | Free connections自由接続 |
| Previewプレビュー | Real-time autoリアルタイム | Auto / Manual toggleAuto / Manual |
| GIFGIF作成 | ✅ Timeline + Auto-Motion✅ | ❌ |
| LIBRARY | Always visible in sidebarサイドバーに常時表示 | L key popupL キーでポップアップ |
| Best for向いている用途 | Quick compositingシンプルな合成 | Complex pipelines複雑なパイプライン |
📁 Adding EFX Modules — Developer Guide📁 EFX モジュール追加ガイド(開発者向け)
The EFX system is fully plugin-based. You can add a new image effect in 2 files and it will automatically appear in both DERU and NODE editors.EFXシステムは完全なプラグイン方式です。2ファイルの変更だけで新しいエフェクトがDERUとNODE両方に自動的に反映されます。
flowchart LR
A["1. Create\nmodules/my-effect.ts"] --> B["2. Import + register in\nregistry.ts"]
B --> C["3. Auto-appears in\nDERU 'Add Effect'\n& NODE palette"]
C --> D["4. Parameters auto-generate\nslider / color / select UI"]
📋 File Structure📋 ファイル構造
// Project structure
src/lib/efx/
├── types.ts // EFXModule, EFXParamDef, Frame, etc.
├── utils.ts // loadImage, dataUrlToCanvas, generateThumbnail
├── registry.ts // EFX_REGISTRY — master list of all modules
└── modules/
├── color.ts // Color Adjust, Invert, Posterize, etc.
├── distortion.ts // Melt, Transform, Feedback, etc.
├── glitch.ts // RGB Glitch, Slit Scan, Fragment, etc.
├── ascii.ts // ASCII Art, Line Edge
└── my-effect.ts // ← YOUR NEW MODULE
🔧 EFXModule Interface🔧 EFXModule インターフェース
Every module must implement this interface (defined in types.ts):すべてのモジュールは次のインターフェースを実装します(types.tsで定義):
interface EFXModule {
id: string; // Unique ID (kebab-case) e.g. 'my-sepia'
name: string; // Display name e.g. 'Sepia Tone'
icon: string; // Emoji icon e.g. '🟤'
category: EFXCategory; // 'filter' | 'distortion' | 'generative' | 'composite'
params: EFXParamDef[]; // Parameter definitions → auto UI
// REQUIRED: Process a single frame
processFrame: (
frame: Frame, // Input image (has .dataUrl)
params: Record<string, any>, // User-adjusted parameter values
context: EFXContext, // Canvas size, frame index, etc.
) => Promise<ProcessedFrameData>; // Return { dataUrl, thumbnail }
// OPTIONAL: Batch processing (for transitions)
processBatch?: (frames, params, ctx, onProgress?) => Promise<...>;
// OPTIONAL: Low-res fast preview
previewFrame?: (frame, params) => Promise<string>;
}
📝 Parameter Types📝 パラメータタイプ
Parameters you define in params[] automatically generate the corresponding UI controls:params[]に定義したパラメータは自動的に対応するUIコントロールを生成します:
| type | UI | Required Fields必須フィールド | Example例 |
range | Slider | min, max, step, default | { key:'amount', label:'Amount', type:'range', default:50, min:0, max:100 } |
color | Color picker | default | { key:'tint', label:'Tint', type:'color', default:'#ff6b9d' } |
select | Dropdown | options[], default | { key:'mode', label:'Mode', type:'select', default:'a', options:[{value:'a',label:'A'}] } |
toggle | Checkbox | default | { key:'on', label:'Enable', type:'toggle', default:true } |
number | Number input | min, max, default | { key:'count', label:'Count', type:'number', default:4, min:1, max:20 } |
🛠️ Helper Utilities🛠️ ヘルパーユーティリティ
Available from ../utils — these handle common Canvas operations:../utilsから利用可能 — Canvas操作の共通処理:
| Function | Description説明 |
dataUrlToCanvas(dataUrl, w, h) | Load a data URL into a Canvas element, scaled to w×hdata URLをCanvasに読み込み、w×hにスケーリング |
loadImage(dataUrl) | Load data URL → HTMLImageElement (for thumbnail gen)data URL → HTMLImageElement(サムネイル生成用) |
generateThumbnail(img, size) | Create a thumbnail data URL (default 150px)サムネイルdata URLを生成(デフォルト150px) |
✨ Example 1: Sepia Effect (Pixel Manipulation)✨ 例1: セピアエフェクト(ピクセル操作)
A complete, minimal module that manipulates pixel data directly:ピクセルデータを直接操作する最小限のモジュール:
// src/lib/efx/modules/sepia.ts
import type { EFXModule, Frame, EFXContext, ProcessedFrameData } from '../types';
import { loadImage, generateThumbnail, dataUrlToCanvas } from '../utils';
export const SepiaEFX: EFXModule = {
id: 'sepia',
name: 'Sepia Tone',
icon: '🟤',
category: 'filter',
params: [
{ key: 'intensity', label: 'Intensity', type: 'range',
default: 100, min: 0, max: 100, step: 1 },
],
processFrame: async (
frame: Frame,
params: Record<string, any>,
context: EFXContext,
): Promise<ProcessedFrameData> => {
// 1. Load input into a canvas
const canvas = await dataUrlToCanvas(
frame.dataUrl, context.canvasWidth, context.canvasHeight
);
const ctx = canvas.getContext('2d')!;
// 2. Get pixel data
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const d = imageData.data;
const mix = params.intensity / 100;
// 3. Apply sepia per pixel
for (let i = 0; i < d.length; i += 4) {
const r = d[i], g = d[i+1], b = d[i+2];
const sr = r * 0.393 + g * 0.769 + b * 0.189;
const sg = r * 0.349 + g * 0.686 + b * 0.168;
const sb = r * 0.272 + g * 0.534 + b * 0.131;
d[i] = Math.min(255, r + (sr - r) * mix);
d[i+1] = Math.min(255, g + (sg - g) * mix);
d[i+2] = Math.min(255, b + (sb - b) * mix);
}
ctx.putImageData(imageData, 0, 0);
// 4. Return result
const dataUrl = canvas.toDataURL('image/png');
const img = await loadImage(dataUrl);
const thumbnail = generateThumbnail(img, 150);
return { dataUrl, thumbnail };
},
};
✨ Example 2: Vignette (Canvas Drawing API)✨ 例2: ビネット(Canvas描画API)
Using the makeModule shorthand helper (from color.ts pattern) for simpler Canvas-based effects:color.tsパターンの makeModule ショートハンドで、シンプルなCanvas描画エフェクト:
// Even shorter using makeModule (copy this pattern from color.ts)
function makeModule(id, name, icon, category, paramDefs, fn): EFXModule {
return {
id, name, icon, category,
params: paramDefs,
processFrame: async (frame, params, context) => {
const canvas = await dataUrlToCanvas(
frame.dataUrl, context.canvasWidth, context.canvasHeight
);
const ctx = canvas.getContext('2d')!;
fn(ctx, canvas.width, canvas.height, params); // ← your logic here
const dataUrl = canvas.toDataURL('image/png');
const img = await loadImage(dataUrl);
return { dataUrl, thumbnail: generateThumbnail(img, 150) };
},
};
}
// Vignette effect using makeModule shorthand
export const VignetteEFX = makeModule(
'vignette', 'Vignette', '🔲', 'filter',
[
{ key: 'strength', label: 'Strength', type: 'range',
default: 50, min: 0, max: 100 },
{ key: 'color', label: 'Color', type: 'color',
default: '#000000' },
],
(ctx, w, h, p) => {
const gradient = ctx.createRadialGradient(
w/2, h/2, w * 0.2, // inner circle
w/2, h/2, w * 0.7, // outer circle
);
gradient.addColorStop(0, 'transparent');
gradient.addColorStop(1, p.color + Math.round(p.strength * 2.55)
.toString(16).padStart(2, '0'));
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, w, h);
},
);
🔌 Step 3: Register in registry.ts🔌 ステップ3: registry.tsに登録
// src/lib/efx/registry.ts
// Add import at the top:
import { SepiaEFX } from './modules/sepia';
import { VignetteEFX } from './modules/vignette';
// Add to EFX_REGISTRY array:
export const EFX_REGISTRY: EFXModule[] = [
// ... existing modules ...
ColorAdjustEFX,
InvertEFX,
// ── Your new modules ──
SepiaEFX, // ← just add here!
VignetteEFX, // ← done!
];
That's it — no other changes needed. Your module will automatically appear in:
• DERU → "Add Effect" dropdown
• NODE → Add Node palette (under the matching category)
• Parameter sliders/pickers are auto-generated from your params[] definition.以上で完了 — 他の変更は不要です。モジュールは自動的に以下に反映されます:
• DERU → 「Add Effect」ドロップダウン
• NODE → Add Node パレット(対応カテゴリに自動分類)
• パラメータのスライダー/ピッカーは params[] 定義から自動生成されます。
📐 Processing Pipeline Deep Dive📐 処理パイプラインの詳細
flowchart TD
INPUT["frame.dataUrl\nPNG data URL string"] --> CANVAS["dataUrlToCanvas\nscaled to canvasWidth × canvasHeight"]
CANVAS --> PROCESS["Your processing logic\ngetImageData / fillRect / drawImage"]
PROCESS --> EXPORT["canvas.toDataURL\n→ full-size PNG data URL"]
EXPORT --> THUMB["generateThumbnail\n→ 150px thumbnail"]
THUMB --> RETURN["return { dataUrl, thumbnail }"]
💡 Tips & Best Practices💡 ヒントとベストプラクティス
- ID naming: Use kebab-case, globally unique (e.g.
my-cool-blur)ID命名: kebab-case、グローバルでユニーク(例: my-cool-blur)
- Category matters: It determines which palette section your module appears inカテゴリが重要: パレットのどのセクションに表示されるか決まります
- Performance: Keep
processFrame fast — it may be called on every slider change in Auto modeパフォーマンス: processFrameは高速に — Autoモードではスライダー変更のたびに呼ばれます
- Pixel loops: Use
getImageData + iterate by 4 (RGBA). Skip transparent pixels with if (d[i+3]===0) continue;ピクセルループ: getImageData + 4ずつイテレート(RGBA)。透明ピクセルは if (d[i+3]===0) continue; でスキップ
- Canvas API: You can use
ctx.filter, ctx.globalCompositeOperation, gradients, or any 2D Canvas featureCanvas API: ctx.filter、ctx.globalCompositeOperation、グラデーション等、Canvas 2D APIの全機能が使えます
- Existing patterns: Study
color.ts (pixel manipulation) and distortion.ts (canvas transforms) for real-world examples既存パターン: color.ts(ピクセル操作)と distortion.ts(Canvas変形)を参考に