AI Image Generation and Editing
zhayujie/CowAgent
Generates or edits images from text prompts through a Python script that picks an image backend based on which API keys are configured.
Implement AI image editing and modification capabilities using the z-ai-web-dev-sdk.
$ npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install Ali-Marandi/Web-Scraper-Framework image-edit --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/Ali-Marandi/Web-Scraper-Framework.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/image-edit .claude/skills/image-edit && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "image-edit" agent skill from https://github.com/Ali-Marandi/Web-Scraper-Framework/tree/main/skills/image-edit into .claude/skills/image-edit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "image-edit", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/Ali-Marandi/Web-Scraper-Framework/tree/main/skills/image-editType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install Ali-Marandi/Web-Scraper-Framework image-edit --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Ali-Marandi/Web-Scraper-Framework.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/image-edit .agents/skills/image-edit && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "image-edit" agent skill from https://github.com/Ali-Marandi/Web-Scraper-Framework/tree/main/skills/image-edit into .agents/skills/image-edit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "image-edit", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install Ali-Marandi/Web-Scraper-Framework image-edit --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Ali-Marandi/Web-Scraper-Framework.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/image-edit .cursor/skills/image-edit && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "image-edit" agent skill from https://github.com/Ali-Marandi/Web-Scraper-Framework/tree/main/skills/image-edit into .cursor/skills/image-edit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "image-edit", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/Ali-Marandi/Web-Scraper-Framework.git --path skills/image-edit--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install Ali-Marandi/Web-Scraper-Framework image-edit --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Ali-Marandi/Web-Scraper-Framework.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/image-edit .gemini/skills/image-edit && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "image-edit" agent skill from https://github.com/Ali-Marandi/Web-Scraper-Framework/tree/main/skills/image-edit into .gemini/skills/image-edit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "image-edit", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install Ali-Marandi/Web-Scraper-Framework image-editInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/Ali-Marandi/Web-Scraper-Framework.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/image-edit .github/skills/image-edit && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "image-edit" agent skill from https://github.com/Ali-Marandi/Web-Scraper-Framework/tree/main/skills/image-edit into .github/skills/image-edit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "image-edit", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install Ali-Marandi/Web-Scraper-Framework image-edit --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/Ali-Marandi/Web-Scraper-Framework.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/image-edit .opencode/skills/image-edit && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "image-edit" agent skill from https://github.com/Ali-Marandi/Web-Scraper-Framework/tree/main/skills/image-edit into .opencode/skills/image-edit/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "image-edit", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
image-editImplement AI image editing and modification capabilities using the z-ai-web-dev-sdk.
Image Edit is an agent skill from Ali-Marandi/Web-Scraper-Framework. Implement AI image editing and modification capabilities using the z-ai-web-dev-sdk. Use this skill when the user needs to edit existing images, create variations, modify visual content, redesign assets, or transform images based on text descriptions. Supports multiple image sizes and returns base64 encoded results. Also includes CLI tool for quick image editing.
Its SKILL.md is about 6.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including scripts (for example `scripts/image-edit.ts`).
It sits in Media & Creative, covering Image editing and Image generation. It works with Zhipu GLM. The repository describes itself as: Flexible and Scalable Web Scraping Framework. The licence is MIT.
3 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit f8af4cd. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 1 file in scripts/ (TypeScript), which the agent can run.
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Image Edit loads about 6.2k tokens when it runs. Until then it costs about 94 tokens; SKILL.md has 699 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from Ali-Marandi/Web-Scraper-Framework at commit f8af4cd, republished under its MIT licence (© Ali-Marandi). 699 words, ~6,189 tokens.
.claude/skills/image-edit/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.This skill guides the implementation of image editing and modification functionality using the z-ai-web-dev-sdk package and CLI tool, enabling intelligent transformation and editing of images based on text descriptions.
Skill Location: {project_path}/skills/image-edit
this skill is located at above path in your project.
Reference Scripts: Example test scripts are available in the {Skill Location}/scripts/ directory for quick testing and reference. See {Skill Location}/scripts/image-edit.ts for a working example.
Image Edit allows you to build applications that modify, transform, and enhance existing images using AI models. Perfect for redesigning assets, creating variations, improving visual content, and transforming images based on textual descriptions.
IMPORTANT: z-ai-web-dev-sdk MUST be used in backend code only. Never use it in client-side code.
The image editing functionality uses the following API method:
await zai.images.generations.edit({
prompt: string, // Required: Description of the edit to apply
images: [{ url: string }], // Required: Array with image URL or base64 data URL
size?: string, // Optional: Output size (default: '1024x1024')
model?: string // Optional: Model name
})Important: The images parameter must be an array of objects with a url property, not a plain string.
API Endpoint: POST /images/generations/edit
Returns: ImageGenerationResponse with base64 encoded edited image
The z-ai-web-dev-sdk package is already installed. Import it as shown in the examples below.
import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
async function editImage(imageSource, editPrompt, outputPath, size = '1024x1024') {
const zai = await ZAI.create();
const response = await zai.images.generations.edit({
prompt: editPrompt,
images: [{ url: imageSource }], // Array of objects with url property
size: size
});
const imageBase64 = response.data[0].base64;
// Save edited image
const buffer = Buffer.from(imageBase64, 'base64');
fs.writeFileSync(outputPath, buffer);
console.log(`Edited image saved to ${outputPath}`);
return outputPath;
}
// Usage - Using remote image URL
await editImage(
'https://example.com/landscape.jpg',
'Transform this landscape into a night scene with stars and moon',
'./landscape_night.png'
);
// Usage - Using local image converted to base64
import { readFileSync } from 'fs';
const imageBuffer = readFileSync('./photo.jpg');
const base64Image = imageBuffer.toString('base64');
const dataUrl = `data:image/jpeg;base64,${base64Image}`;
await editImage(
dataUrl,
'Change the cat to a dog, keep everything else the same',
'./dog_version.png'
);import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
async function createVariation(imageSource, baseDescription, variation, outputPath, size = '1024x1024') {
const zai = await ZAI.create();
// Combine base description with variation request
const prompt = `${baseDescription}, ${variation}`;
const response = await zai.images.generations.edit({
prompt: prompt,
images: [{ url: imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
fs.writeFileSync(outputPath, buffer);
return {
path: outputPath,
prompt: prompt,
variation: variation
};
}
// Usage - Create variations from original image
await createVariation(
'https://example.com/headshot.jpg',
'Professional headshot photo',
'with blue background instead of gray',
'./headshot_blue.png'
);
await createVariation(
'./smartphone.png',
'Product photo of smartphone',
'on wooden table instead of white background',
'./product_wood.png'
);import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
// Supported sizes
const SUPPORTED_SIZES = [
'1024x1024', // Square
'768x1344', // Portrait
'864x1152', // Portrait
'1344x768', // Landscape
'1152x864', // Landscape
'1440x720', // Wide landscape
'720x1440' // Tall portrait
];
async function editImageWithSize(imageSource, editPrompt, size, outputPath) {
if (!SUPPORTED_SIZES.includes(size)) {
throw new Error(`Unsupported size: ${size}. Use one of: ${SUPPORTED_SIZES.join(', ')}`);
}
const zai = await ZAI.create();
const response = await zai.images.generations.edit({
prompt: editPrompt,
images: [{ url: imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
fs.writeFileSync(outputPath, buffer);
return {
path: outputPath,
size: size,
fileSize: buffer.length
};
}
// Usage - Edit with different aspect ratios
await editImageWithSize(
'./logo.png',
'Redesign the logo to be more modern and minimalist',
'1024x1024',
'./logo_redesigned.png'
);
await editImageWithSize(
'https://example.com/portrait.jpg',
'Transform the portrait to landscape orientation, sunset lighting',
'1344x768',
'./portrait_landscape.png'
);The z-ai CLI tool provides a convenient way to edit images directly from the command line.
# Edit image with full options
z-ai image-edit --prompt "Change the background to sunset colors" --image "./photo.png" --output "./edited.png"
# Short form
z-ai image-edit -p "Make it darker and moodier" -i "./original.jpg" -o "./moody.png"
# Specify output size
z-ai image-edit -p "Redesign in modern style" -i "./design.png" -o "./modern.png" -s 1344x768
# Using remote image URL
z-ai image-edit -p "Convert to landscape orientation" -i "https://example.com/photo.png" -o "./landscape.png" -s 1344x768--prompt, -p: Required - Description of the edit to apply--image, -i: Required - Original image URL or local file path--output, -o: Required - Output image file path (PNG format)--size, -s: Optional - Image size, default is 1024x1024--help, -h: Optional - Display help information1024x1024, 768x1344, 864x1152, 1344x768, 1152x864, 1440x720, 720x1440# Redesign existing asset
z-ai image-edit -p "Redesign the logo with gradients and modern styling" -i "./logo.png" -o "./logo_v2.png" -s 1024x1024
# Change color scheme
z-ai image-edit -p "Change color scheme to blue and white, professional style" -i "./original.png" -o "./recolored.png" -s 1440x720
# Style transformation
z-ai image-edit -p "Transform to oil painting style, vibrant colors" -i "./photo.jpg" -o "./oil_painting.png" -s 1152x864
# Background replacement
z-ai image-edit -p "Replace background with modern office setting" -i "./portrait.png" -o "./new_background.png" -s 1344x768
# Lighting adjustment
z-ai image-edit -p "Adjust to golden hour lighting, warm tones" -i "./landscape.jpg" -o "./golden_hour.png" -s 1024x1024
# Element modification
z-ai image-edit -p "Replace the red car with a blue motorcycle" -i "./scene.png" -o "./modified.png" -s 1344x768
# Mood transformation
z-ai image-edit -p "Transform to dark moody atmosphere with dramatic lighting" -i "./bright.jpg" -o "./moody.png" -s 1440x720
# Using remote image URL
z-ai image-edit -p "Add a hat to the person" -i "https://example.com/photo.png" -o "./result.png" -s 1024x1024import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
import path from 'path';
async function batchEditImages(editInstructions, outputDir, size = '1024x1024') {
const zai = await ZAI.create();
// Ensure output directory exists
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const results = [];
for (let i = 0; i < editInstructions.length; i++) {
try {
const instruction = editInstructions[i];
const filename = `edited_${i + 1}.png`;
const outputPath = path.join(outputDir, filename);
const response = await zai.images.generations.edit({
prompt: instruction.prompt,
images: [{ url: instruction.imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
fs.writeFileSync(outputPath, buffer);
results.push({
success: true,
instruction: instruction.prompt,
path: outputPath,
size: buffer.length
});
console.log(`✓ Edited: ${filename}`);
} catch (error) {
results.push({
success: false,
instruction: editInstructions[i].prompt,
error: error.message
});
console.error(`✗ Failed: ${editInstructions[i].prompt} - ${error.message}`);
}
}
return results;
}
// Usage - Create multiple variations from the same image
const editInstructions = [
{
imageSource: './original.jpg',
prompt: 'Change background to blue gradient'
},
{
imageSource: './original.jpg',
prompt: 'Transform to black and white, high contrast'
},
{
imageSource: './original.jpg',
prompt: 'Add sunset lighting effects'
}
];
const results = await batchEditImages(editInstructions, './edited-images');
console.log(`Edited ${results.filter(r => r.success).length} images`);import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
class ImageEditingService {
constructor(outputDir = './edited-images') {
this.outputDir = outputDir;
this.zai = null;
this.editHistory = [];
}
async initialize() {
this.zai = await ZAI.create();
if (!fs.existsSync(this.outputDir)) {
fs.mkdirSync(this.outputDir, { recursive: true });
}
}
generateFilename(editPrompt) {
const hash = crypto
.createHash('md5')
.update(`${editPrompt}-${Date.now()}`)
.digest('hex')
.substring(0, 8);
return `edited_${hash}.png`;
}
async edit(imageSource, editPrompt, options = {}) {
const {
size = '1024x1024',
saveToHistory = true,
filename = null
} = options;
const response = await this.zai.images.generations.edit({
prompt: editPrompt,
images: [{ url: imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
// Determine output path
const outputFilename = filename || this.generateFilename(editPrompt);
const outputPath = path.join(this.outputDir, outputFilename);
fs.writeFileSync(outputPath, buffer);
const result = {
path: outputPath,
imageSource: imageSource,
editPrompt: editPrompt,
size: size,
fileSize: buffer.length,
timestamp: new Date().toISOString()
};
// Save to history
if (saveToHistory) {
this.editHistory.push(result);
}
return result;
}
async createVariations(imageSource, basePrompt, variations, options = {}) {
const results = [];
for (const variation of variations) {
const fullPrompt = `${basePrompt}, ${variation}`;
const result = await this.edit(imageSource, fullPrompt, options);
result.variation = variation;
results.push(result);
}
return results;
}
getEditHistory() {
return this.editHistory;
}
clearHistory() {
this.editHistory = [];
}
}
// Usage
const service = new ImageEditingService();
await service.initialize();
// Single edit
const edited = await service.edit(
'./original.jpg',
'Transform to watercolor painting style',
{ size: '1024x1024' }
);
// Multiple variations from the same image
const variations = await service.createVariations(
'https://example.com/product.png',
'Professional product photo',
[
'with blue background',
'with wooden surface',
'with dramatic lighting'
]
);
console.log('Edit history:', service.getEditHistory());import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
async function applyStyleTransfer(imageSource, content, style, outputPath, size = '1024x1024') {
const zai = await ZAI.create();
const prompt = `${content} transformed into ${style} style, maintain composition and subject`;
const response = await zai.images.generations.edit({
prompt: prompt,
images: [{ url: imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
fs.writeFileSync(outputPath, buffer);
return {
path: outputPath,
content: content,
style: style
};
}
// Usage - Apply different styles to the same image
await applyStyleTransfer(
'./portrait.jpg',
'Portrait photograph',
'oil painting',
'./portrait_oil.png'
);
await applyStyleTransfer(
'https://example.com/city.jpg',
'City landscape',
'watercolor',
'./city_watercolor.png'
);
await applyStyleTransfer(
'./product.png',
'Product photo',
'minimalist illustration',
'./product_minimal.png'
);import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
async function replaceElement(imageSource, baseScene, replaceWhat, replaceWith, outputPath, size = '1024x1024') {
const zai = await ZAI.create();
const prompt = `${baseScene}, replace ${replaceWhat} with ${replaceWith}, keep everything else identical`;
const response = await zai.images.generations.edit({
prompt: prompt,
images: [{ url: imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
fs.writeFileSync(outputPath, buffer);
return {
path: outputPath,
modification: `${replaceWhat} → ${replaceWith}`
};
}
// Usage
await replaceElement(
'./workspace.jpg',
'Office workspace with laptop',
'laptop',
'desktop computer with dual monitors',
'./workspace_desktop.png'
);
await replaceElement(
'https://example.com/living-room.jpg',
'Living room interior with sofa',
'blue sofa',
'brown leather sofa',
'./living_room_leather.png'
);function buildEditPrompt(baseDescription, modification, preserveElements = []) {
const components = [
baseDescription,
modification
];
if (preserveElements.length > 0) {
components.push(`keep ${preserveElements.join(', ')} unchanged`);
}
components.push('maintain overall composition');
return components.filter(Boolean).join(', ');
}
// Usage
const editPrompt = buildEditPrompt(
'Professional headshot photo',
'change background to modern office',
['lighting', 'pose', 'expression']
);
// Result: "Professional headshot photo, change background to modern office, keep lighting, pose, expression unchanged, maintain overall composition"function selectSizeForEdit(editType) {
const sizeMap = {
'background-change': '1440x720',
'style-transfer': '1024x1024',
'color-adjustment': '1024x1024',
'element-replacement': '1344x768',
'composition-change': '1152x864',
'portrait-edit': '768x1344',
'landscape-edit': '1344x768'
};
return sizeMap[editType] || '1024x1024';
}
// Usage
const size = selectSizeForEdit('background-change');
await editImage('Replace background with beach scene', './beach_bg.png', size);import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
async function safeEditImage(imageSource, editPrompt, size, outputPath, retries = 3) {
let lastError;
for (let attempt = 1; attempt <= retries; attempt++) {
try {
const zai = await ZAI.create();
const response = await zai.images.generations.edit({
prompt: editPrompt,
images: [{ url: imageSource }],
size: size
});
if (!response.data || !response.data[0] || !response.data[0].base64) {
throw new Error('Invalid response from image editing API');
}
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
fs.writeFileSync(outputPath, buffer);
return {
success: true,
path: outputPath,
attempts: attempt
};
} catch (error) {
lastError = error;
console.error(`Attempt ${attempt} failed:`, error.message);
if (attempt < retries) {
// Wait before retry (exponential backoff)
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}
return {
success: false,
error: lastError.message,
attempts: retries
};
}import express from 'express';
import ZAI from 'z-ai-web-dev-sdk';
import fs from 'fs';
import path from 'path';
const app = express();
app.use(express.json());
app.use('/edited-images', express.static('edited-images'));
let zaiInstance;
const outputDir = './edited-images';
async function initZAI() {
zaiInstance = await ZAI.create();
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
}
app.post('/api/edit-image', async (req, res) => {
try {
const {
imageSource, // URL or base64 data URL
editPrompt,
size = '1024x1024',
baseDescription = ''
} = req.body;
if (!imageSource || !editPrompt) {
return res.status(400).json({
error: 'imageSource and editPrompt are required'
});
}
// Combine base description with edit instruction
const fullPrompt = baseDescription
? `${baseDescription}, ${editPrompt}`
: editPrompt;
const response = await zaiInstance.images.generations.edit({
prompt: fullPrompt,
images: [{ url: imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
const filename = `edited_${Date.now()}.png`;
const filepath = path.join(outputDir, filename);
fs.writeFileSync(filepath, buffer);
res.json({
success: true,
imageUrl: `/edited-images/${filename}`,
editPrompt: fullPrompt,
size: size
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
});
app.post('/api/create-variations', async (req, res) => {
try {
const {
imageSource, // URL or base64 data URL
baseDescription,
variations,
size = '1024x1024'
} = req.body;
if (!imageSource || !baseDescription || !variations || !Array.isArray(variations)) {
return res.status(400).json({
error: 'imageSource, baseDescription and variations array are required'
});
}
const results = [];
for (const variation of variations) {
const fullPrompt = `${baseDescription}, ${variation}`;
const response = await zaiInstance.images.generations.edit({
prompt: fullPrompt,
images: [{ url: imageSource }],
size: size
});
const imageBase64 = response.data[0].base64;
const buffer = Buffer.from(imageBase64, 'base64');
const filename = `variation_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.png`;
const filepath = path.join(outputDir, filename);
fs.writeFileSync(filepath, buffer);
results.push({
variation: variation,
imageUrl: `/edited-images/${filename}`
});
}
res.json({
success: true,
results: results
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
});
initZAI().then(() => {
app.listen(3000, () => {
console.log('Image editing API running on port 3000');
});
});#!/bin/bash
# Batch edit images with different styles
echo "Creating style variations..."
ORIGINAL_IMAGE="./product.jpg"
BASE="Professional product photo of laptop"
z-ai image-edit -p "$BASE, modern minimalist style, white background" -i "$ORIGINAL_IMAGE" -o "./variations/minimal.png" -s 1024x1024
z-ai image-edit -p "$BASE, dramatic lighting, dark background" -i "$ORIGINAL_IMAGE" -o "./variations/dramatic.png" -s 1024x1024
z-ai image-edit -p "$BASE, on wooden desk, natural lighting" -i "$ORIGINAL_IMAGE" -o "./variations/natural.png" -s 1024x1024
echo "Variations created successfully!"Issue: "SDK must be used in backend"
Issue: Invalid size parameter
Issue: Edited image doesn't match intention
Issue: CLI command not found
Issue: Image quality loss after editing
Issue: Inconsistent results across variations
Background Changes:
"[Subject description], replace background with [new background], maintain subject lighting and pose"Style Transfers:
"[Current description] transformed into [style name] style, preserve composition and key elements"Element Replacement:
"[Scene description], replace [element A] with [element B], keep everything else identical"Color Adjustments:
"[Image description], change color scheme to [colors], maintain contrast and composition"1024x1024 - Square (Best for general editing)768x1344 - Portrait864x1152 - Portrait1344x768 - Landscape1152x864 - Landscape1440x720 - Wide landscape720x1440 - Tall portrait© Ali-Marandi, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (scripts) in skills/image-edit of Ali-Marandi/Web-Scraper-Framework.
Open the folder on GitHubat commit f8af4cd
Image Edit next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Image Edit this skillAli-Marandi/Web-Scraper-Framework | 107 | — | ~6.2k | Automated safety check: Pass | MIT | |
| AI Image Generation and Editingzhayujie/CowAgent | 47k | — | ~1.3k | Automated safety check: Pass | MIT | |
| Generate Imageynulihao/AgentSkillOS | 617 | 10 repos | ~1.7k | Automated safety check: Notes | None | |
| GPT Image Generation CLIwuyoscar/GPT-Image2-Skill | 5.7k | — | ~2.5k | Automated safety check: Notes | MIT | |
| Image Generationjjyaoao/HelloAgents | 3.2k | 1 repos | ~3.8k | Automated safety check: Pass | MIT | |
| NanobananaReScienceLab/opc-skills | 1.8k | 1 repos | ~1.3k | Automated safety check: Pass | Apache-2.0 |
zhayujie/CowAgent
Generates or edits images from text prompts through a Python script that picks an image backend based on which API keys are configured.
ynulihao/AgentSkillOS
Generate or edit images using AI models (FLUX, Gemini). An agent skill from ynulihao/AgentSkillOS.
wuyoscar/GPT-Image2-Skill
Generates and edits images with GPT Image 2 or 2.5 through a packaged CLI and a prompt gallery, after settling which model fits the request.
jjyaoao/HelloAgents
Implement AI image generation capabilities using the z-ai-web-dev-sdk.
ReScienceLab/opc-skills
Generate and edit images using Google Gemini 3 Pro Image (Nano Banana Pro).
ZSeven-W/craft-skills
Generate new raster assets that must contain native pixel transparency, then verify the untouched PNG or WebP before delivery.
Ali-Marandi/Web-Scraper-Framework
Activate this skill when the user wants deep, multi-round academic paper collection for a survey or literature review.
Ali-Marandi/Web-Scraper-Framework
帮用户准备面试。基于目标 JD、公司、岗位方向,生成"高频面试题 + 参考回答 + 行为面 / 技术面 / Case 面分类题库",并产出可打印的『面试备战手册』。当用户说"帮我准备面试""明天有面试 / 后天面试""面试题""面经""模拟面试""我要面 X 公司 Y 岗位""帮我准备 STAR 故事""怎么回答这道面试题""自我介绍 / 离职原因 / 优缺点 怎么答",必须触发本…
Ali-Marandi/Web-Scraper-Framework
给定一份 JD 和一份现有简历,做"JD 拆解 + 简历定向改写"。拆 JD 抽出硬技能、软技能、加分项;对照简历做 gap 分析;产出针对该岗位重写后的简历,突出相关经验、补齐关键词缺口、并保留候选人真实经历不编造。当用户说"针对这个岗位 / 这家公司改简历""帮我对一下这个 JD""我想投这个职位你看怎么改""把这份简历针对 X 公司优化""做一份定向版简历",或同时给出 JD 文本 +…
Ali-Marandi/Web-Scraper-Framework
帮助用户梳理求职意向、生成目标岗位画像,并维护一份结构化的"岗位投递追踪表"。当用户说"我想换工作 / 不知道投什么岗 / 帮我看看我适合什么岗位 / 帮我管理投递进度 / 我投了好几家但记不住状态了 / 想做一个求职 OKR / 整理一下求职方向",或上传简历但没说要改简历时,应该主动触发本 skill。本 skill 也适用于实习生、应届生、转行候选人在求职启动阶段做"自我盘点 +…
Ali-Marandi/Web-Scraper-Framework
从零生成或全面优化一份中文简历,并导出 docx / pdf / markdown 多种格式。用 STAR 法则改写经历、做 ATS 关键词覆盖率检查、根据行业(互联网产品 / 技术 / 金融 / 通用)选模板。当用户说"帮我写简历 / 优化简历 / 简历不会写 / 我的简历太弱了 / 简历看起来不专业 / 简历改一改 / 给我做个简历模板 / 简历导出 / 简历加点关键词",或者上传…
Ali-Marandi/Web-Scraper-Framework
AI 解梦大师。用户描述梦境,智能追问关键细节后,从三个视角(周公解梦/心理分析/赛博神棍)生成解读,输出结构化 JSON 供前端渲染"梦境解析卡"。
Works with
Categories
Implement AI image editing and modification capabilities using the z-ai-web-dev-sdk. Image Edit is an agent skill from Ali-Marandi/Web-Scraper-Framework. Implement AI image editing and modification capabilities using the z-ai-web-dev-sdk.
Image Edit fits situations like: the user needs to edit existing images; create variations; modify visual content; redesign assets.
Run `npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a claude-code`. Or copy the skill folder (skills/image-edit in Ali-Marandi/Web-Scraper-Framework) into .claude/skills/image-edit in your project. Claude Code loads it when a task matches its description.
Run `npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a codex`. Or copy the skill folder (skills/image-edit in Ali-Marandi/Web-Scraper-Framework) into .agents/skills/image-edit in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Ali-Marandi/Web-Scraper-Framework --skill image-edit -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/image-edit, .gemini/skills/image-edit, .github/skills/image-edit and .opencode/skills/image-edit in your project.
Going by SKILL.md and its folder, Image Edit needs TypeScript for the scripts in its folder. Our summary lists: Node.js.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Image Edit is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.2k tokens (SKILL.md is roughly 25k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Image Edit: AI Image Generation and Editing (zhayujie/CowAgent, 47k stars), Generate Image (ynulihao/AgentSkillOS, 617 stars), GPT Image Generation CLI (wuyoscar/GPT-Image2-Skill, 5.7k stars) and Image Generation (jjyaoao/HelloAgents, 3.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Ali-Marandi (a GitHub user) maintains it in Ali-Marandi/Web-Scraper-Framework, which has 107 GitHub stars. The repository holds 12 skills in this directory. The repository was last updated on August 31, 2026.
Source: Ali-Marandi/Web-Scraper-Framework on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.