office-sprite
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOffice Sprite Generator
Office精灵图生成指南
Create game-ready sprites for the Claude Office Visualizer using Nano Banana MCP and ImageMagick.
为Claude Office Visualizer创建可直接用于游戏的精灵图,使用Nano Banana MCP和ImageMagick工具。
Project Context
项目背景
The Claude Office Visualizer uses a 45-degree front/top-down perspective (NOT isometric). This means:
- Objects are viewed primarily from the front
- Slight top-down angle shows a bit of the top surface
- You do NOT see multiple side faces like in isometric views
- Similar to classic 2D RPGs or top-down office games
Art Style: Retro 16-bit pixel art with clean edges and limited anti-aliasing.
Claude Office Visualizer采用45度前俯视角(非等轴测视角)。这意味着:
- 物体主要从正面展示
- 轻微的俯角可显示少量顶面
- 不会像等轴测视图那样显示多个侧面
- 类似经典2D RPG或俯视角办公室游戏的视角
美术风格:复古16位像素美术,边缘清晰,抗锯齿效果有限。
Workflow
工作流程
Step 1: Generate with Nano Banana
步骤1:使用Nano Banana生成
Use mcpl to call Nano Banana with this prompt template:
bash
mcpl call nanobanana generate_image '{
"prompt": "[OBJECT DESCRIPTION], front view with slight top-down angle, NOT isometric, pixel art style, retro 16-bit game sprite, isolated on solid magenta background #FF00FF, clean edges, no shadows on background, game sprite asset, centered composition, no text, no watermarks, simple design",
"output_path": "/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png"
}'Prompt Variables:
- : Detailed description of the object (e.g., "Office water cooler dispenser with blue water bottle jug on top of white dispenser stand with hot and cold taps")
[OBJECT DESCRIPTION] - : Sprite filename (e.g., "watercooler", "desk", "plant")
[NAME]
使用mcpl调用Nano Banana,采用以下提示模板:
bash
mcpl call nanobanana generate_image '{
"prompt": "[OBJECT DESCRIPTION], front view with slight top-down angle, NOT isometric, pixel art style, retro 16-bit game sprite, isolated on solid magenta background #FF00FF, clean edges, no shadows on background, game sprite asset, centered composition, no text, no watermarks, simple design",
"output_path": "/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png"
}'提示变量说明:
- :物体的详细描述(例如:"办公室饮水机,白色机身顶部放置蓝色水桶,带有冷热出水龙头")
[OBJECT DESCRIPTION] - :精灵图文件名(例如:"watercooler"、"desk"、"plant")
[NAME]
Step 2: VALIDATE THE IMAGE
步骤2:验证图片
CRITICAL: Before proceeding with ImageMagick processing, you MUST:
-
Copy the generated image to the raw location:bash
cp "/Users/probello/nanobanana-images/temp_images/[UUID].png" \ "/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png" -
View the image using the Read tool to verify:
- Perspective is correct (front view, NOT isometric/3D cube view)
- Subject is centered and fully visible
- Background is solid magenta (may have black letterboxing on sides)
- Art style matches retro pixel art aesthetic
-
If the image is NOT correct:
- Regenerate with adjusted prompt
- Do NOT proceed to ImageMagick processing
- Common issues:
- Isometric view: Add "NOT isometric, front facing view" more emphatically
- Wrong style: Specify "16-bit pixel art, retro game sprite" more clearly
- Cut off subject: Add "full object visible, not cropped"
重要提示:在进行ImageMagick处理之前,您必须:
-
将生成的图片复制到原始文件目录:bash
cp "/Users/probello/nanobanana-images/temp_images/[UUID].png" \ "/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png" -
使用查看工具查看图片,验证以下内容:
- 视角正确(正面视图,非等轴测/3D立方体视图)
- 主体居中且完整可见
- 背景为纯品红色(两侧可能有黑边)
- 美术风格匹配复古像素美术审美
-
如果图片不符合要求:
- 调整提示词重新生成
- 不要进行ImageMagick处理
- 常见问题:
- 等轴测视图:更强调地添加"NOT isometric, front facing view"
- 风格错误:更明确地指定"16-bit pixel art, retro game sprite"
- 主体被裁剪:添加"full object visible, not cropped"
Step 3: Process with ImageMagick
步骤3:使用ImageMagick处理
Only after validation passes, remove the magenta background using the helper script:
bash
undefined只有在验证通过后,才能使用辅助脚本移除品红色背景:
bash
undefinedUsing the helper script (recommended)
使用辅助脚本(推荐)
/Users/probello/Repos/claude-office/.claude/skills/office-sprite/scripts/process_sprite.sh
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png
The script uses a **multi-pass workflow** combining FFmpeg and ImageMagick:
1. **FFmpeg geq filter**: Removes pixels where R≈B and G is low (purple/magenta hues)
2. **ImageMagick multi-pass**: Catches remaining bright magenta shades (#FF00FF, #CC00CC, etc.)
3. **ImageMagick dark purple cleanup**: Removes dark edge pixels like rgb(32,0,31)
For legacy flood-fill method (faster but may leave pink edges):
```bash
process_sprite.sh input.png output.png --legacyManual multi-pass workflow (if script unavailable):
bash
INPUT="/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png"
OUTPUT="/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png"/Users/probello/Repos/claude-office/.claude/skills/office-sprite/scripts/process_sprite.sh
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png
/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png
该脚本结合FFmpeg和ImageMagick采用**多阶段处理流程**:
1. **FFmpeg geq滤镜**:移除R≈B且G值较低的像素(紫色/品红色调)
2. **ImageMagick多阶段处理**:捕获剩余的亮品红色调(#FF00FF、#CC00CC等)
3. **ImageMagick深紫色清理**:移除深紫色边缘像素,如rgb(32,0,31)
如需使用传统的漫水填充方法(速度更快但可能留下粉色边缘):
```bash
process_sprite.sh input.png output.png --legacy手动多阶段处理流程(当脚本不可用时):
bash
INPUT="/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME]_raw.png"
OUTPUT="/Users/probello/Repos/claude-office/frontend/public/sprites/[NAME].png"Step 1: FFmpeg - remove purple hue pixels (R≈B, G low)
Step 1: FFmpeg - remove purple hue pixels (R≈B, G low)
ffmpeg -y -i "$INPUT"
-vf "geq=r='r(X,Y)':g='g(X,Y)':b='b(X,Y)':a='if(between(r(X,Y)-b(X,Y),-60,60)*lt(g(X,Y),r(X,Y)*0.7)*lt(g(X,Y),b(X,Y)*0.7)*gt(r(X,Y)+b(X,Y),100),0,alpha(X,Y))'"
-update 1 -frames:v 1 /tmp/step1.png
-vf "geq=r='r(X,Y)':g='g(X,Y)':b='b(X,Y)':a='if(between(r(X,Y)-b(X,Y),-60,60)*lt(g(X,Y),r(X,Y)*0.7)*lt(g(X,Y),b(X,Y)*0.7)*gt(r(X,Y)+b(X,Y),100),0,alpha(X,Y))'"
-update 1 -frames:v 1 /tmp/step1.png
ffmpeg -y -i "$INPUT"
-vf "geq=r='r(X,Y)':g='g(X,Y)':b='b(X,Y)':a='if(between(r(X,Y)-b(X,Y),-60,60)*lt(g(X,Y),r(X,Y)*0.7)*lt(g(X,Y),b(X,Y)*0.7)*gt(r(X,Y)+b(X,Y),100),0,alpha(X,Y))'"
-update 1 -frames:v 1 /tmp/step1.png
-vf "geq=r='r(X,Y)':g='g(X,Y)':b='b(X,Y)':a='if(between(r(X,Y)-b(X,Y),-60,60)*lt(g(X,Y),r(X,Y)*0.7)*lt(g(X,Y),b(X,Y)*0.7)*gt(r(X,Y)+b(X,Y),100),0,alpha(X,Y))'"
-update 1 -frames:v 1 /tmp/step1.png
Step 2: ImageMagick - remove bright magenta shades
Step 2: ImageMagick - remove bright magenta shades
magick /tmp/step1.png -alpha set -channel RGBA
-fuzz 20% -transparent "magenta"
-fuzz 15% -transparent "#CC00CC"
-fuzz 15% -transparent "#880088"
-fuzz 15% -transparent "#660066"
/tmp/step2.png
-fuzz 20% -transparent "magenta"
-fuzz 15% -transparent "#CC00CC"
-fuzz 15% -transparent "#880088"
-fuzz 15% -transparent "#660066"
/tmp/step2.png
magick /tmp/step1.png -alpha set -channel RGBA
-fuzz 20% -transparent "magenta"
-fuzz 15% -transparent "#CC00CC"
-fuzz 15% -transparent "#880088"
-fuzz 15% -transparent "#660066"
/tmp/step2.png
-fuzz 20% -transparent "magenta"
-fuzz 15% -transparent "#CC00CC"
-fuzz 15% -transparent "#880088"
-fuzz 15% -transparent "#660066"
/tmp/step2.png
Step 3: ImageMagick - remove dark purple edge pixels
Step 3: ImageMagick - remove dark purple edge pixels
magick /tmp/step2.png
-fuzz 8% -fill none
-opaque "rgb(32,0,31)"
-opaque "rgb(34,0,31)"
-trim +repage -strip
"$OUTPUT"
-fuzz 8% -fill none
-opaque "rgb(32,0,31)"
-opaque "rgb(34,0,31)"
-trim +repage -strip
"$OUTPUT"
magick /tmp/step2.png
-fuzz 8% -fill none
-opaque "rgb(32,0,31)"
-opaque "rgb(34,0,31)"
-trim +repage -strip
"$OUTPUT"
-fuzz 8% -fill none
-opaque "rgb(32,0,31)"
-opaque "rgb(34,0,31)"
-trim +repage -strip
"$OUTPUT"
Verify transparency
Verify transparency
magick "$OUTPUT" -format "Size: %wx%h, Opaque: %[opaque]" info:
**Why multi-pass?** AI-generated images often have anti-aliased edges that blend the subject with the magenta background. Single-pass removal leaves pink/purple fringing. The multi-pass approach targets different shades of magenta/purple for thorough cleanupmagick "$OUTPUT" -format "Size: %wx%h, Opaque: %[opaque]" info:
**为什么要多阶段处理?** AI生成的图像通常带有抗锯齿边缘,会使主体与品红色背景融合。单阶段移除会留下粉色/紫色边缘。多阶段处理针对不同色调的品红/紫色进行彻底清理。Step 4: Verify Final Sprite
步骤4:验证最终精灵图
View the processed sprite with the Read tool to confirm:
- Clean transparency (no magenta fringing)
- Sprite edges are intact (not eroded)
- Correct dimensions for game use
使用查看工具查看处理后的精灵图,确认:
- 透明效果干净(无品红色边缘)
- 精灵图边缘完整(未被侵蚀)
- 尺寸符合游戏使用要求
Step 5: Update Game Code
步骤5:更新游戏代码
In , sprites are loaded and displayed like this:
OfficeGameV2.tsxtypescript
// Add texture state
const [spriteTexture, setSpriteTexture] = useState<Texture | null>(null);
// Load texture in useEffect
useEffect(() => {
const loadTextures = async () => {
try {
const texture = await Assets.load("/sprites/[NAME].png");
setSpriteTexture(texture);
} catch (e) {
console.warn("Failed to load sprite:", e);
}
};
loadTextures();
}, []);
// Render sprite with fallback to placeholder
<pixiContainer x={X_POS} y={Y_POS}>
{spriteTexture ? (
<pixiSprite
texture={spriteTexture}
anchor={0.5}
scale={SCALE_FACTOR}
/>
) : (
<pixiGraphics draw={drawPlaceholder} />
)}
</pixiContainer>Scale Calculation:
- Target display width / Sprite actual width = scale factor
- Example: For 50px display width with 189px sprite: or
scale={50/189}scale={0.26}
在中,精灵图的加载和显示方式如下:
OfficeGameV2.tsxtypescript
// Add texture state
const [spriteTexture, setSpriteTexture] = useState<Texture | null>(null);
// Load texture in useEffect
useEffect(() => {
const loadTextures = async () => {
try {
const texture = await Assets.load("/sprites/[NAME].png");
setSpriteTexture(texture);
} catch (e) {
console.warn("Failed to load sprite:", e);
}
};
loadTextures();
}, []);
// Render sprite with fallback to placeholder
<pixiContainer x={X_POS} y={Y_POS}>
{spriteTexture ? (
<pixiSprite
texture={spriteTexture}
anchor={0.5}
scale={SCALE_FACTOR}
/>
) : (
<pixiGraphics draw={drawPlaceholder} />
)}
</pixiContainer>缩放计算:
- 目标显示宽度 / 精灵图实际宽度 = 缩放系数
- 示例:对于显示宽度50px、实际宽度189px的精灵图:或
scale={50/189}scale={0.26}
Furniture Reference
家具参考
Current furniture sizes from :
furnitureManager.ts| Type | Width | Height | Notes |
|---|---|---|---|
| desk | 140px | 80px | With chair position |
| plant | 40px | 40px | Potted plant |
| watercooler | 50px | 50px | Water dispenser |
| filing_cabinet | 60px | 80px | Metal cabinet |
| couch | 120px | 60px | Office couch |
| table | 100px | 60px | Meeting table |
Additional elements from :
OfficeGameV2.tsx| Element | Approx Size | Notes |
|---|---|---|
| Wall clock | 88x88px | Analog clock face |
| Whiteboard | 330x170px | With todo display |
| Elevator | 128x160px | With doors |
| Safety sign | 140x100px | Days without incident |
来自的当前家具尺寸:
furnitureManager.ts| 类型 | 宽度 | 高度 | 说明 |
|---|---|---|---|
| desk | 140px | 80px | 包含椅子位置 |
| plant | 40px | 40px | 盆栽植物 |
| watercooler | 50px | 50px | 饮水机 |
| filing_cabinet | 60px | 80px | 金属文件柜 |
| couch | 120px | 60px | 办公沙发 |
| table | 100px | 60px | 会议桌 |
来自的其他元素:
OfficeGameV2.tsx| 元素 | 近似尺寸 | 说明 |
|---|---|---|
| Wall clock | 88x88px | 模拟时钟表盘 |
| Whiteboard | 330x170px | 包含待办事项显示 |
| Elevator | 128x160px | 带门的电梯 |
| Safety sign | 140x100px | 无事故天数标识 |
Output Location
输出位置
All sprites go to:
/Users/probello/Repos/claude-office/frontend/public/sprites/- - Original generated image (keep for reference)
[name]_raw.png - - Processed sprite with transparency
[name].png
所有精灵图保存至:
/Users/probello/Repos/claude-office/frontend/public/sprites/- - 原始生成图像(保留作为参考)
[name]_raw.png - - 带透明背景的处理后精灵图
[name].png
Anti-Patterns
反模式(错误做法)
DO NOT:
- Skip the validation step - always view the raw image first
- Use instead of flood fill - it removes ALL matching pixels
-transparent - Proceed with isometric/wrong perspective images - regenerate instead
- Use white or black as chroma key - they appear in subjects
- Forget to trim - wastes texture memory
DO:
- Always validate before processing
- Use flood fill from corners for clean background removal
- Keep raw images as backup
- Verify final sprite has transparency ()
Opaque: False - Test sprite in game before moving to next asset
请勿:
- 跳过验证步骤 - 务必先查看原始图像
- 使用替代漫水填充 - 它会移除所有匹配像素
-transparent - 继续使用等轴测/错误视角的图像 - 重新生成
- 使用白色或黑色作为色度键 - 它们会出现在主体中
- 忘记裁剪 - 浪费纹理内存
请:
- 处理前始终进行验证
- 使用从角落开始的漫水填充来干净地移除背景
- 保留原始图像作为备份
- 验证最终精灵图是否具有透明效果()
Opaque: False - 在处理下一个资源前,先在游戏中测试精灵图