codepet 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/codepet.js CHANGED
@@ -487,6 +487,11 @@ function doPopup() {
487
487
  const script = path.join(__dirname, '..', 'scripts', 'polaroid_image.py');
488
488
  try {
489
489
  execSync(`${PYTHON} "${script}" ${pet.character} ${scene}`, { encoding: 'utf-8', stdio: 'inherit' });
490
+ const photoPath = path.join(os.homedir(), '.codepet', 'photo.png');
491
+ if (fs.existsSync(photoPath)) {
492
+ const openCmd = process.platform === 'win32' ? 'start ""' : process.platform === 'darwin' ? 'open' : 'xdg-open';
493
+ execSync(`${openCmd} "${photoPath}"`, { stdio: 'ignore', shell: true });
494
+ }
490
495
  } catch {}
491
496
  }
492
497
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codepet",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "在编程软件里养电子宠物 — 支持 Claude Code / Codex / Cursor / VS Code 等 10+ 平台",
5
5
  "main": "core/index.js",
6
6
  "bin": {
@@ -47,6 +47,7 @@
47
47
  "scripts/img2ascii.py",
48
48
  "scripts/img2emoji.py",
49
49
  "scripts/polaroid.py",
50
+ "scripts/polaroid_image.py",
50
51
  "scripts/pet_card.py",
51
52
  "scripts/render_to_image.py",
52
53
  "scripts/show_all.py",
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env python3
2
+ """拍立得相框 — 生成 PNG 图片版(Windows 和通用平台)"""
3
+
4
+ import sys, os, json, platform
5
+ from PIL import Image, ImageDraw, ImageFont
6
+
7
+ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
8
+ SPRITE_DIR = os.path.join(SCRIPT_DIR, "..", "sprites")
9
+ PET_JSON = os.path.join(os.path.expanduser("~"), ".codepet", "pet.json")
10
+ OUTPUT = os.path.join(os.path.expanduser("~"), ".codepet", "photo.png")
11
+
12
+ SCENE_ZH = {
13
+ 'normal': '日常', 'happy': '开心的瞬间', 'sleep': '睡着了',
14
+ 'eat': '在吃东西', 'pet': '被摸摸的样子', 'worry': '有点紧张',
15
+ }
16
+
17
+ def load_font(size):
18
+ """跨平台加载字体"""
19
+ system = platform.system()
20
+ candidates = []
21
+ if system == "Darwin":
22
+ candidates = [
23
+ "/System/Library/Fonts/PingFang.ttc",
24
+ "/System/Library/Fonts/Hiragino Sans GB.ttc",
25
+ ]
26
+ elif system == "Windows":
27
+ windir = os.environ.get("WINDIR", "C:\\Windows")
28
+ candidates = [
29
+ os.path.join(windir, "Fonts", "msyh.ttc"),
30
+ os.path.join(windir, "Fonts", "simhei.ttf"),
31
+ os.path.join(windir, "Fonts", "arial.ttf"),
32
+ ]
33
+ else:
34
+ candidates = [
35
+ "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
36
+ "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
37
+ "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
38
+ ]
39
+ for fp in candidates:
40
+ if os.path.exists(fp):
41
+ try:
42
+ return ImageFont.truetype(fp, size)
43
+ except:
44
+ continue
45
+ return ImageFont.load_default()
46
+
47
+ def main():
48
+ character = sys.argv[1] if len(sys.argv) > 1 else 'bagayalu'
49
+ scene = sys.argv[2] if len(sys.argv) > 2 else 'normal'
50
+
51
+ img_path = os.path.join(SPRITE_DIR, character, f"{scene}.png")
52
+ if not os.path.exists(img_path):
53
+ img_path = os.path.join(SPRITE_DIR, f"{character}.png")
54
+
55
+ name = character
56
+ try:
57
+ with open(PET_JSON, 'r', encoding='utf-8') as f:
58
+ pet = json.load(f)
59
+ name = pet.get('nickname', pet.get('name', character))
60
+ except:
61
+ pass
62
+
63
+ scene_zh = SCENE_ZH.get(scene, '一个瞬间')
64
+
65
+ # 加载角色图片
66
+ sprite = Image.open(img_path).convert("RGBA")
67
+
68
+ # 拍立得尺寸
69
+ padding = 40
70
+ bottom_area = 120
71
+ photo_w = sprite.width + padding * 2
72
+ photo_h = sprite.height + padding + bottom_area
73
+
74
+ # 白色拍立得底板
75
+ card = Image.new("RGBA", (photo_w, photo_h), (255, 255, 255, 255))
76
+
77
+ # 贴角色图片
78
+ card.paste(sprite, (padding, padding), sprite)
79
+
80
+ # 画边框阴影
81
+ draw = ImageDraw.Draw(card)
82
+ draw.rectangle([0, 0, photo_w - 1, photo_h - 1], outline=(200, 200, 200), width=2)
83
+
84
+ # 底部文字
85
+ font_caption = load_font(18)
86
+ font_studio = load_font(14)
87
+
88
+ caption = f"📸 刚才抓拍到了{name}{scene_zh}..."
89
+ studio = "🐋 Ai小蓝鲸照相馆"
90
+
91
+ caption_y = sprite.height + padding + 15
92
+ studio_y = caption_y + 35
93
+
94
+ draw.text((padding, caption_y), caption, fill=(80, 80, 80), font=font_caption)
95
+ draw.text((padding, studio_y), studio, fill=(140, 140, 140), font=font_studio)
96
+
97
+ # 保存
98
+ os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)
99
+ card_rgb = Image.new("RGB", card.size, (255, 255, 255))
100
+ card_rgb.paste(card, mask=card.split()[3])
101
+ card_rgb.save(OUTPUT, "PNG", quality=95)
102
+
103
+ # 不在这里打开,让 Node.js 调用方负责打开
104
+ print(OUTPUT)
105
+
106
+ if __name__ == '__main__':
107
+ main()