koishi-plugin-image-prompt 1.0.0
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/LICENSE +674 -0
- package/lib/index.d.ts +28 -0
- package/lib/index.js +802 -0
- package/package.json +28 -0
- package/readme.md +46 -0
- package/src/index.ts +874 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,802 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name2 in all)
|
|
7
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/index.ts
|
|
20
|
+
var src_exports = {};
|
|
21
|
+
__export(src_exports, {
|
|
22
|
+
Config: () => Config,
|
|
23
|
+
apply: () => apply,
|
|
24
|
+
inject: () => inject,
|
|
25
|
+
name: () => name,
|
|
26
|
+
usage: () => usage
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(src_exports);
|
|
29
|
+
var import_koishi = require("koishi");
|
|
30
|
+
var name = "image-prompt";
|
|
31
|
+
var inject = ["http", "logger", "i18n"];
|
|
32
|
+
var usage = `
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
此插件直接调用 OpenAI 兼容的 Chat Completions 接口生成图片
|
|
36
|
+
|
|
37
|
+
请在插件设置中填写:
|
|
38
|
+
|
|
39
|
+
- API 服务器地址(baseUrl)
|
|
40
|
+
- 使用的模型(model)
|
|
41
|
+
- API 密钥(apiKey)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
此项目所需的koishi服务: 'http', 'logger', 'i18n'
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
`;
|
|
48
|
+
var logger = new import_koishi.Logger(name);
|
|
49
|
+
var defaultCommands = [
|
|
50
|
+
{
|
|
51
|
+
name: "手办化",
|
|
52
|
+
prompt: "Your task is to create a photorealistic, masterpiece-quality image of a 1/7 scale commercialized figurine based on the user's character. The final image must be in a realistic style and environment.\n\n**Crucial Instruction on Face & Likeness:** The figurine's face is the most critical element. It must be a perfect, high-fidelity 3D translation of the character from the source image. The sculpt must be sharp, clean, and intricately detailed, accurately capturing the original artwork's facial structure, eye style, expression, and hair. The final result must be immediately recognizable as the same character, elevated to a premium physical product standard. Do NOT generate a generic or abstract face.\n\n**Scene Composition (Strictly follow these details):**\n1. **Figurine & Base:** Place the figure on a computer desk. It must stand on a simple, circular, transparent acrylic base WITHOUT any text or markings.\n2. **Computer Monitor:** In the background, a computer monitor must display 3D modeling software (like ZBrush or Blender) with the digital sculpt of the very same figurine visible on the screen.\n3. **Artwork Display:** Next to the computer screen, include a transparent acrylic board with a wooden base. This board holds a print of the original 2D artwork that the figurine is based on.\n4. **Environment:** The overall setting is a desk, with elements like a keyboard to enhance realism. The lighting should be natural and well-lit, as if in a room.",
|
|
53
|
+
enabled: true,
|
|
54
|
+
custom: false,
|
|
55
|
+
maxImages: 1,
|
|
56
|
+
waitTimeout: 50,
|
|
57
|
+
defaultImageUrls: []
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "手办化2",
|
|
61
|
+
prompt: "Use the nano-banana model to create a 1/7 scale commercialized figure of thecharacter in the illustration, in a realistic styie and environment.Place the figure on a computer desk, using a circular transparent acrylic basewithout any text.On the computer screen, display the ZBrush modeling process of the figure.Next to the computer screen, place a BANDAl-style toy packaging box printedwith the original artwork.",
|
|
62
|
+
enabled: true,
|
|
63
|
+
custom: false,
|
|
64
|
+
maxImages: 1,
|
|
65
|
+
waitTimeout: 50,
|
|
66
|
+
defaultImageUrls: []
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "手办化3",
|
|
70
|
+
prompt: "Your primary mission is to accurately convert the subject from the user's photo into a photorealistic, masterpiece quality, 1/7 scale PVC figurine, presented in its commercial packaging.\n\n**Crucial First Step: Analyze the image to identify the subject's key attributes (e.g., human male, human female, animal, specific creature) and defining features (hair style, clothing, expression). The generated figurine must strictly adhere to these identified attributes.** This is a mandatory instruction to avoid generating a generic female figure.\n\n**Top Priority - Character Likeness:** The figurine's face MUST maintain a strong likeness to the original character. Your task is to translate the 2D facial features into a 3D sculpt, preserving the identity, expression, and core characteristics. If the source is blurry, interpret the features to create a sharp, well-defined version that is clearly recognizable as the same character.\n\n**Scene Details:**\n1. **Figurine:** The figure version of the photo I gave you, with a clear representation of PVC material, placed on a round plastic base.\n2. **Packaging:** Behind the figure, there should be a partially transparent plastic and paper box, with the character from the photo printed on it.\n3. **Environment:** The entire scene should be in an indoor setting with good lighting.",
|
|
71
|
+
enabled: true,
|
|
72
|
+
custom: false,
|
|
73
|
+
maxImages: 1,
|
|
74
|
+
waitTimeout: 50,
|
|
75
|
+
defaultImageUrls: []
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "coser化",
|
|
79
|
+
prompt: "Create a realistic cosplay photograph of the character in the image. The cosplayer should be wearing a high-quality costume that accurately replicates the character's outfit. Include appropriate props and background setting that matches the character's universe. Focus on accurate representation of costume details and realistic materials. Draw the picture for me with the background of a comic convention. East-asian face.",
|
|
80
|
+
enabled: true,
|
|
81
|
+
custom: false,
|
|
82
|
+
maxImages: 1,
|
|
83
|
+
waitTimeout: 50,
|
|
84
|
+
defaultImageUrls: []
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "mc化",
|
|
88
|
+
prompt: "Transform the image into a Minecraft-style character. Create a blocky, pixelated version of the character using Minecraft's visual style. Include appropriate Minecraft environment and elements in the background. The generated entities must be Minecraft-style entities or blocks/structures.",
|
|
89
|
+
enabled: true,
|
|
90
|
+
custom: false,
|
|
91
|
+
maxImages: 1,
|
|
92
|
+
waitTimeout: 50,
|
|
93
|
+
defaultImageUrls: []
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "线稿化",
|
|
97
|
+
prompt: "手绘线稿,精细的铅笔素描风格,纸上绘画效果,清晰的线条勾勒,适度的细节刻画。画面中包含绘画工具(如铅笔、橡皮、卷笔刀、素描本)自然散落在旁,呈现创作中的氛围。线条黑白灰调性,无色彩,突出纸张纹理和手绘质感,专注于形体结构和轮廓表现",
|
|
98
|
+
enabled: true,
|
|
99
|
+
custom: false,
|
|
100
|
+
maxImages: 1,
|
|
101
|
+
waitTimeout: 50,
|
|
102
|
+
defaultImageUrls: []
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "爱上我了",
|
|
106
|
+
prompt: "生成一张三格漫画,画面上方三分之一处的左半部分是第一格,右半部分是第二格,画面下方占总画面三分之二的位置是第三格。要求人物长相服装与参考图完全一致。第一格为人物的面部特写,眼睛睁大,眼神中带着一丝惊讶,嘴巴被一只手轻轻捂住,旁边配有一个 “!” 的符号,整体神态呈现出意外、略带羞怯的感觉,动作上是单手掩口,姿态显得较为娇俏。第二格也是人物的面部特写,眼睛眯起,呈现出笑意,嘴巴微张,那只捂住嘴的手还保持着动作,同时有 “噗~” 的拟声词,神态是开心、俏皮的,仿佛是忍不住要笑出声,动作上延续了掩口的姿态,却多了几分活泼的情绪。第三格背景是有云朵的天空,画面只出现了人物的上半身,人物画风与参考图完全一致。人物的发丝被风吹起,眼睛弯弯,面带柔和的笑容,脸颊还有淡淡的红晕。她姿态放松,身体略向前倾,双手背在身后,整体神态是自信且温柔,呈现出一种大方又迷人的状态。第三格左边有圆形对话框,写着“你觉得我漂亮”。右侧下方有圆形对话框,写着“那是因为你已经爱上我了,笨蛋”。",
|
|
107
|
+
enabled: true,
|
|
108
|
+
custom: true,
|
|
109
|
+
maxImages: 2,
|
|
110
|
+
waitTimeout: 60,
|
|
111
|
+
defaultImageUrls: []
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "合并图片",
|
|
115
|
+
prompt: "将两张图片合并为一张",
|
|
116
|
+
enabled: true,
|
|
117
|
+
custom: true,
|
|
118
|
+
maxImages: 2,
|
|
119
|
+
waitTimeout: 60,
|
|
120
|
+
defaultImageUrls: []
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: "修图",
|
|
124
|
+
prompt: "修复图片中的缺陷",
|
|
125
|
+
enabled: true,
|
|
126
|
+
custom: true,
|
|
127
|
+
maxImages: 1,
|
|
128
|
+
waitTimeout: 60,
|
|
129
|
+
defaultImageUrls: []
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: "手办化4",
|
|
133
|
+
prompt: "Please accurately transform the subject in this photo into a realistic, masterpiece-worthy 1/7 scale PVC figurine. This figurine must possess 3D dimensionality, and the PVC texture must be clearly represented. The figurine is placed in a figurine display cabinet made of multi-layered glass; appropriate space should be left between the top of the figurine and the upper shelf, and the figurine must be paired with a transparent base. The indoor scene must be visible through the glass. Different figurines can be placed on other shelves, but they should exhibit a natural depth of field and blurred effect to further enhance the sense of spatial depth and highlight the main figurine. The scene requires a bright main light source, and the display cabinet should be embedded with dim LED strip lights; the overall light and reflections must blend naturally with the scene. The frame angle does not need to be fixed in a specific orientation.\nDetail Specifications: Every part of the figurine must be 3D dimensional, and flat or two-dimensional effects are prohibited; under no circumstances shall contour lines or outlines appear; when repairing missing parts of the figurine, no low-quality content shall appear; if repairing a human figure, it is necessary to ensure normal limb shape, coordinated movements, and reasonable proportions of all parts; if the original photo is not a full-body shot, try to supplement the figurine into a full-body form as much as possible; the expression, movements, and angle of the human figurine must be completely consistent with the original photo, but it must be 3D dimensional; the head of the human figurine must not be too large, the legs must not be too short, and the overall figure must not look short; for chibi cartoon subjects, their original proportions shall be retained, but they must be 3D dimensional; if the subject is an animal, its fur should be simplified to make it more like a figurine product; attention must be paid to following the perspective principle of objects appearing larger when closer and smaller when farther away.",
|
|
134
|
+
enabled: true,
|
|
135
|
+
custom: false,
|
|
136
|
+
maxImages: 1,
|
|
137
|
+
waitTimeout: 50,
|
|
138
|
+
defaultImageUrls: []
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "手办化5",
|
|
142
|
+
prompt: "Realistic PVC figure based on the game screenshot character, exact pose replication highly detailed textures PVC material with subtle sheen and smooth paint finish, placed on an indoor wooden computer desk (with subtle desk items like a figure box/mouse), illuminated by soft indoor light (mix of desk lamp and natural window light) for realistic shadows and highlights, macro photography style,high resolution,sharp focus on the figure,shallow depth of field (desk background slightly blurred but visible), no stylization,true-to-reference color and design, 1:1scale.",
|
|
143
|
+
enabled: true,
|
|
144
|
+
custom: false,
|
|
145
|
+
maxImages: 1,
|
|
146
|
+
waitTimeout: 50,
|
|
147
|
+
defaultImageUrls: []
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "手办化6",
|
|
151
|
+
prompt: "Create a premium, collectible 1/7 scale standalone figurine based on the image, meticulously replicating the character, made from smooth PVC and ABS plastic with a professional matte finish. It stands on a minimalist transparent acrylic base. Next to it is its retail packaging box displaying the price and brand information, with the figure wrapped in plastic inside the slightly larger box. They are naturally arranged on a clean wooden table surrounded by reference books, with a bookshelf in the background and soft afternoon sunlight streaming through the window. Photo-realistic, DSLR effect, depth of field, bokeh background.",
|
|
152
|
+
enabled: true,
|
|
153
|
+
custom: false,
|
|
154
|
+
maxImages: 1,
|
|
155
|
+
waitTimeout: 50,
|
|
156
|
+
defaultImageUrls: []
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: "Q版化",
|
|
160
|
+
prompt: "((chibi style)), ((super-deformed)), ((head-to-body ratio 1:2)), ((huge head, tiny body)), ((smooth rounded limbs)), ((soft balloon-like hands and feet)), ((plump cheeks)), ((childlike big eyes)), ((simplified facial features)), ((smooth matte skin, no pores)), ((soft pastel color palette)), ((gentle ambient lighting, natural shadows)), ((same facial expression, same pose, same background scene)), ((seamless integration with original environment, correct perspective and scale)), ((no outline or thin soft outline)), ((high resolution, sharp focus, 8k, ultra-detailed)), avoid: realistic proportions, long limbs, sharp edges, harsh lighting, wrinkles, blemishes, thick black outlines, low resolution, blurry, extra limbs, distorted face",
|
|
161
|
+
enabled: true,
|
|
162
|
+
custom: false,
|
|
163
|
+
maxImages: 1,
|
|
164
|
+
waitTimeout: 50,
|
|
165
|
+
defaultImageUrls: []
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: "cos化",
|
|
169
|
+
prompt: "Generate a highly detailed photo of a real-life girl cosplaying this illustration, at Comiket. Exactly replicate the same pose, body posture, hand gestures, facial expression, and camera framing as in the original illustration. Keep the same angle, perspective, and composition, without any deviation.",
|
|
170
|
+
enabled: true,
|
|
171
|
+
custom: false,
|
|
172
|
+
maxImages: 1,
|
|
173
|
+
waitTimeout: 50,
|
|
174
|
+
defaultImageUrls: []
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "cos自拍",
|
|
178
|
+
prompt: "Generate a first-person perspective (POV) snapshot of a cosplayer in a cluttered bedroom. The cosplayer's hairstyle and anime costume must exactly match the subject in the reference image. She holds a phone in front of her face with both hands, completely covering her face. The phone screen is the focal point of the image, displaying the uploaded picture. The background is a room filled with posters on the walls and a slightly messy bed. The image should have a casual, informal snapshot quality with a slightly low-resolution and grainy texture, lit by natural indoor lighting.",
|
|
179
|
+
enabled: true,
|
|
180
|
+
custom: false,
|
|
181
|
+
maxImages: 1,
|
|
182
|
+
waitTimeout: 50,
|
|
183
|
+
defaultImageUrls: []
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: "痛屋化",
|
|
187
|
+
prompt: "[ABSOLUTE PRIORITY AND NON-NEGOTIABLE DIRECTIVE] Based on the provided reference image, generate a hyper-detailed photograph of a maximalist otaku shrine with a strict, uncompromising requirement: all character-related elements—including figures, posters, bedding patterns, and the PC wallpaper—must be a 90%+ faithful, pixel-perfect replication of the character in the reference image. Strictly maintain the precise facial features, hairstyle, outfit, and expression with zero artistic reinterpretation or stylistic variation. With this core rule, create the scene at a 16:9 aspect ratio. The room is densely packed from floor to ceiling with merchandise that is an exact reproduction of this source character. The entire space is bathed in a moody, immersive ambient glow dominated by the reference character's primary color scheme (e.g., deep purple), which is sharply contrasted by a focused, brighter white light from a monitor screen bar lamp, creating dramatic visual layers. The walls are a collage made of posters and prints that are direct, unaltered copies of the reference image itself; the glass cabinets are cluttered with high-poly figures that are perfect 1:1 replicas of the reference character model; and the ultrawide monitor clearly displays the original reference image as its wallpaper. The final image must be a photorealistic, lived-in sanctuary, defined by its obsessive and flawless fidelity to the source character.",
|
|
188
|
+
enabled: true,
|
|
189
|
+
custom: false,
|
|
190
|
+
maxImages: 1,
|
|
191
|
+
waitTimeout: 50,
|
|
192
|
+
defaultImageUrls: []
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: "痛屋化2",
|
|
196
|
+
prompt: "Transform the uploaded indoor photo into a Japanese-style ita-room with the following specific requirements: Walls: Generate multi-size posters/scrolls (A2/A3/banner mixed arrangement) in an orderly matrix; no watermarks or garbled text. Curtains and bedding: Fully replace with themed patterns while retaining fabric folds and textures; pillowcases and life-sized cushions use the same character design. Display: Add glass display cabinets and open shelves, densely displaying themed figurines, acrylic stands, badge boards, and boxed peripherals of the same theme; arrange them in groups by height and color system. Desk: Keep the original equipment and light and shadow, only replace the screensaver/wallpaper with themed images; organize the wires neatly. Lighting: Add soft RGB light strips (along the ceiling and desk edges), coordinated with the main color, avoiding overexposure and color overflow. Texture: Realistic materials for PVC figurines, spray-painted paper, acrylic, and cotton fabrics; natural glass reflections without ghosting. Consistency: The face, hair color, and clothing details of the character on all carriers (posters/cushions/stands/box art) must maintain the same character and art style. Constraints (negative): No brand logos, watermarks, typos, distorted faces, perspective errors, repeated textures, over-sharpening, or noise.",
|
|
197
|
+
enabled: true,
|
|
198
|
+
custom: false,
|
|
199
|
+
maxImages: 1,
|
|
200
|
+
waitTimeout: 50,
|
|
201
|
+
defaultImageUrls: []
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "痛车化",
|
|
205
|
+
prompt: "A Xiaomi SU7 electric sedan with a professional 'itasha' wrap, parked on a rain-slicked, neon-lit city street at dusk. Accurately depict the Xiaomi SU7 body shape, grille-less front fascia, slim headlights, taillights, wheel design, and logo placements. The entire car is covered in a vibrant, high-resolution decal featuring multiple dynamic poses and expressions of ONLY the provided anime character. The glossy finish reflects colorful city lights, making the character artwork pop.Seamless full-body wrap integrating hood, doors, and rear quarter panels. Dynamic three-quarter front view showcasing the hood and side artwork.",
|
|
206
|
+
enabled: true,
|
|
207
|
+
custom: false,
|
|
208
|
+
maxImages: 1,
|
|
209
|
+
waitTimeout: 50,
|
|
210
|
+
defaultImageUrls: []
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: "孤独的我",
|
|
214
|
+
prompt: "Generate a hyper-realistic photograph with RAW photo quality, captured by a top-tier camera. The image must exhibit realistic skin textures, rich lighting layers, and a natural depth of field. Absolutely no anime, cartoon, CG, or painted elements are allowed—the result must be a 100% authentic photographic representation. The scene is set in a restaurant, captured from a first-person perspective. I am sitting alone, holding chopsticks in one hand and a phone in the other, displaying a photo of a beautiful cosplayer. In the background, the same cosplayer (dressed as the anime character) is dining with her boyfriend, feeding him a bite of food. The composition should evoke a sense of loneliness and contrast between the observer and the observed.",
|
|
215
|
+
enabled: true,
|
|
216
|
+
custom: false,
|
|
217
|
+
maxImages: 1,
|
|
218
|
+
waitTimeout: 50,
|
|
219
|
+
defaultImageUrls: []
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: "第一视角",
|
|
223
|
+
prompt: "At the venue of Japan's Comic Market Doujinshi Sales Event commonly known as Comiket a real Chinese boy or girl of the same gender as the character in the original image is sitting directly opposite you wearing a costume consistent with the one in the original image. A double meal set including hamburgers and French fries is placed on your table with crumpled tissues and some food scraps scattered beside it creating a strong sense of realism. Your Android phone is casually laid on the table and its screen displays an unedited original image of the character. The person is engaging in intimate interaction with you gazing gently into your eyes leaning slightly towards you and placing one hand softly on your arm.You are holding a hamburger or a few French fries.",
|
|
224
|
+
enabled: true,
|
|
225
|
+
custom: false,
|
|
226
|
+
maxImages: 1,
|
|
227
|
+
waitTimeout: 50,
|
|
228
|
+
defaultImageUrls: []
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: "第三视角",
|
|
232
|
+
prompt: "A scene in a bright, modern McDonald’s or KFC restaurant at night, consistent with the visual style of the provided original image (no AI-generated imagery). In front of you (the viewer), there are foods like a hamburger and a small serving of French fries (with a visibly small portion) on the table, along with a crumpled used tissue, a few food crumbs (adding a sense of realism), and an Android phone (with a character displayed on the screen)—you are holding a hamburger or a French fry in your hand. At a very nearby separate table (not a shared table)—so close that it’s within easy sight—two Chinese people are sitting and engaging in intimate interactions (e.g., gentle eye contact, leaning slightly towards each other, or one resting a hand lightly on the other’s arm). One of them is a coser dressed exactly as the character on your Android phone, with the coser’s gender strictly corresponding to the character’s gender (male coser remains male, female coser remains female, no gender reversal) and matching that of the character in the provided original image; the other is a man. On their table, there is a two-person set meal, and both figures are slightly blurred (not overly so). The overall atmosphere blends a relaxed dining vibe with character-related elements, featuring natural lighting, and adheres to the visual style of the original image.",
|
|
233
|
+
enabled: true,
|
|
234
|
+
custom: false,
|
|
235
|
+
maxImages: 1,
|
|
236
|
+
waitTimeout: 50,
|
|
237
|
+
defaultImageUrls: []
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: "鬼图",
|
|
241
|
+
prompt: "Convert the Input Image into a Convincing, Found-Footage Style Cryptid Sighting Photograph 1. The image should depict a [insert creature name or description - e.g., slender, pale humanoid; multi-limbed, insect-like entity; shadowy, canine-like beast], and the creature’s appearance must be highly similar to that in the original image. The creature should be spotted in a hyperrealistic and eerily desolate location, such as [e.g., an abandoned industrial complex at night, a remote, snow-covered mountain pass, the murky depths of a forgotten urban canal, a desolate rural road in the dead of winter]. 2. The shot must appear accidental, amateurish, and raw, as if captured spontaneously by a low-fidelity device like a [e.g., degraded VHS camcorder, grainy security camera, old disposable camera with flash, an infrared trail cam that's seen better days]. 3. To maximize the unsettling authenticity, the image quality should be significantly imperfect: featuring extreme [e.g., heavy digital noise, pronounced film grain, severe motion blur making details indistinct, a strong, disorienting lens flare, being significantly out of focus, or displaying visible static and tracking lines]. The creature should be partially obscured and difficult to clearly discern, perhaps hidden by [e.g., dense, skeletal tree branches; thick, unnatural fog; distorted reflections on murky water; the jagged silhouette of derelict machinery; or existing within deep, oppressive shadows]. 4. The lighting is critically dim and unsettling, possibly at [e.g., the darkest hour before dawn, a moonless midnight, or starkly illuminated by a harsh, direct, and slightly malfunctioning camera flash that overexposes parts of the scene].5. The overall feeling should evoke profound unease, dread, and a sense of witnessing something truly inexplicable and horrifying. Emphasize an atmosphere of isolation, decay, and the uncanny. 6. Keywords: cryptozoology, urban legend, paranormal, faked sighting, unsettling, horror, cryptid, grotesque, eerie, found footage, degraded quality, creature feature.",
|
|
242
|
+
enabled: true,
|
|
243
|
+
custom: false,
|
|
244
|
+
maxImages: 1,
|
|
245
|
+
waitTimeout: 50,
|
|
246
|
+
defaultImageUrls: []
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "贴纸化",
|
|
250
|
+
prompt: "Generate A creative collage artwork based on the provided input image. The artwork should be created using a variety of materials such as paper, fabric, and found objects to achieve a textured, layered look. The composition should capture the essence of the original subject while incorporating collage techniques such as cutting, layering, and mixed media. The final piece should have a dynamic",
|
|
251
|
+
enabled: true,
|
|
252
|
+
custom: false,
|
|
253
|
+
maxImages: 1,
|
|
254
|
+
waitTimeout: 50,
|
|
255
|
+
defaultImageUrls: []
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: "玉足",
|
|
259
|
+
prompt: "Use the attached image as the exact protagonist (identity lock), maintaining exact facial features, hairstyle, and distinctive characteristics from the reference image. 1/7 scale commercial figurine, nano-banana model, hyper-detailed PVC figure. A character sitting on the ground with body positioned on the left side of the frame. From the character's perspective: RIGHT LEG fully extended straight forward, while LEFT LEG bent at the knee with foot flat on the ground. From viewer's perspective: The extended RIGHT LEG of the character appears on the LEFT SIDE of the frame, creating strong forced perspective with LOW ANGLE SHOT (foot size 2x larger than head). The character's extended right foot (viewer's left side) must be in sharp focus with soft milky-white skin tone, subtle pink undertones, and sole facing viewer at 45°, showing exactly 5 distinct toes with natural nail beds and delicate skin texture. Smooth, soft skin with a healthy, supple appearance. Arms crossed on chest, realistic hand-painted details, translucent PVC material effect. No background elements - focus entirely on the figurine's pose and foot details.",
|
|
260
|
+
enabled: true,
|
|
261
|
+
custom: false,
|
|
262
|
+
maxImages: 1,
|
|
263
|
+
waitTimeout: 50,
|
|
264
|
+
defaultImageUrls: []
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "玩偶化",
|
|
268
|
+
prompt: "Reshape the character in the picture into a top-tier collectible *fumo*, with a fully soft and dynamic pose, and place it on the character theme fur pad. High-precision material, hand-stitched, the texture of the plush fabric and the clothing is truly distinct.\nIts eyes are the signature large embroidered semi-oval ones, without pupils, presenting a flat, sleepy or listless expression.\nThe main light source is soft diffused light, highlighting the fluffy feeling and soft texture, without overexposure. Powerful fill light eliminates dead black, and details are fully visible. The background is a blurred depth of field by the window, and the product packaging box is faintly visible on the side and rear. The sticker on the packaging box should be the original uploaded image.\nMuseum-level photography quality, every detail of the body is intact, and the embroidered facial features are exquisite and accurate.\nProhibited: Any 2D elements or direct copying of the original image, plastic feel, hard texture, blurred face, misaligned facial features, and loss of details.",
|
|
269
|
+
enabled: true,
|
|
270
|
+
custom: false,
|
|
271
|
+
maxImages: 1,
|
|
272
|
+
waitTimeout: 50,
|
|
273
|
+
defaultImageUrls: []
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: "cos相遇",
|
|
277
|
+
prompt: "A lively comic convention scene with a bustling real-world environment, featuring the original manga-style character from the input image, retaining her exact colorful design, unique art style, and distinct features (including her specific hair color, outfit, and expression). The character remains a vibrant, non-realistic manga-style figure, not a 2D flat plane but preserving her original artistic depth and color palette. She stands in a crowded convention hall with colorful cosplay booths and attendees. Facing her is a cosplayer dressed in an identical outfit, mimicking her pose, both positioned at a 45-degree angle toward the viewer. The background is a detailed, realistic comic convention with vivid colors, dynamic crowd, and cosplay elements, creating a surreal blend of the manga character’s vibrant, non-realistic style with a real-world setting. Emphasize the magical encounter between the manga character and her cosplayer counterpart.",
|
|
278
|
+
enabled: true,
|
|
279
|
+
custom: false,
|
|
280
|
+
maxImages: 1,
|
|
281
|
+
waitTimeout: 50,
|
|
282
|
+
defaultImageUrls: []
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: "三视图",
|
|
286
|
+
prompt: "a 3-view orthographic drawing of a young woman from a photo, showing front, right side, and back views. Realistic rendering, professional character sheet style, on a white background",
|
|
287
|
+
enabled: true,
|
|
288
|
+
custom: false,
|
|
289
|
+
maxImages: 1,
|
|
290
|
+
waitTimeout: 50,
|
|
291
|
+
defaultImageUrls: []
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: "穿搭拆解",
|
|
295
|
+
prompt: "A professional e-commerce fashion showcase featuring the clothing worn by the character from the input image, presented in a clean, studio-style setting. The outfit is decomposed into individual pieces (e.g., top, bottom, jacket, shoes, accessories), each clearly displayed and arranged in an organized, visually appealing layout. Each clothing item retains the exact design, color, texture, and details from the original image, showcased with crisp lighting and high-definition clarity. The background is minimalistic, white or neutral, to emphasize the clothing details, suitable for an online retail platform. The presentation includes subtle annotations or labels for each item, ensuring a polished, catalog-style look for wear and styling inspiration.",
|
|
296
|
+
enabled: true,
|
|
297
|
+
custom: false,
|
|
298
|
+
maxImages: 1,
|
|
299
|
+
waitTimeout: 50,
|
|
300
|
+
defaultImageUrls: []
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "拆解图",
|
|
304
|
+
prompt: "Convert the people in the photos to the style of a model kit box, rendered in isometric perspective. Label the box with the title“Zhogue”. Inside the box, a gouda-styled robotic version of the person in the photo is displayed, along with its essentials (such as cosmetics, bags, or other items) redesigned as a futuristic mechanical accessory. The box should resemble a real Gunpla box, with technical illustrations, manual-style details, and sci-fi fonts. Next to the box, the actual gouda-style robot itself is also displayed, rendered in a realistic and lifelike style on the outside of the packaging, similar to the official Bandai propaganda renderings.",
|
|
305
|
+
enabled: true,
|
|
306
|
+
custom: false,
|
|
307
|
+
maxImages: 1,
|
|
308
|
+
waitTimeout: 50,
|
|
309
|
+
defaultImageUrls: []
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: "角色界面",
|
|
313
|
+
prompt: "Transform the input person image into a game character selection interface. Display the character on the right side as a full-body portrait, standing upright at a 45-degree angle facing both the screen and the left-side selection module, mimicking a selected state in a video game. Retain the person image's facial features, expression, and hairstyle, but adapt the clothing to a game-inspired style (e.g., fantasy armor, sci-fi suit, or RPG adventurer outfit) with intricate details, vibrant textures, and thematic accessories, while preserving the original clothing's color scheme and general aesthetic. If the input is a half-body image, seamlessly complete the lower body, matching the game-style clothing and proportions. On the left side, present a sleek interface with selectable options including game-style clothing variations (e.g., different armor sets, robes, tactical gear), martial stats (e.g., strength, agility), equipment (e.g., swords, gadgets, shields), and health points, styled as interactive game UI elements with clear labels and modern design. Arrange the layout to mimic a video game character selection screen, with a smooth, unified background gradient (e.g., dark blue to soft gray) for a cohesive, natural transition across the image. Use consistent, cinematic lighting and subtle glow effects to enhance the game-like atmosphere while maintaining the character's real-world facial essence.",
|
|
314
|
+
enabled: true,
|
|
315
|
+
custom: false,
|
|
316
|
+
maxImages: 1,
|
|
317
|
+
waitTimeout: 50,
|
|
318
|
+
defaultImageUrls: []
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: "角色设定",
|
|
322
|
+
prompt: "为我生成人物的角色设定(Character Design),比例设定(不同身高对比、头身比等),三视图(正面、侧面、背面),表情设定(Expression Sheet) → 就是你发的那种图,动作设定(Pose Sheet) → 各种常见姿势,服装设定(Costume Design)",
|
|
323
|
+
enabled: true,
|
|
324
|
+
custom: false,
|
|
325
|
+
maxImages: 1,
|
|
326
|
+
waitTimeout: 50,
|
|
327
|
+
defaultImageUrls: []
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: "3D打印",
|
|
331
|
+
prompt: "Please transform the object in the uploaded image into a collectible figurine.Behind it, place a figurine box printed with the object's image and its name. Next to it, add a high-end 3D printer that is currently printing the figurine. In front of the figurine box, add a round plastic base for the figurine to stand on.The PVC material of the base should have a crystal-clear, translucent texture, and set the entire scene indoors.",
|
|
332
|
+
enabled: true,
|
|
333
|
+
custom: false,
|
|
334
|
+
maxImages: 1,
|
|
335
|
+
waitTimeout: 50,
|
|
336
|
+
defaultImageUrls: []
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
name: "微型化",
|
|
340
|
+
prompt: "A high-resolution advertising photograph of a realistic, miniature [PRODUCT] held delicately between a person's thumb and index finger. clean and white background, studio lighting, soft shadows. The hand is well-groomed, natural skin tone, and positioned to highlight the product's shape and details. The product appears extremely small but hyper-detailed and brand-accurate, centered in the frame with a shallow depth of field. Emulates luxury product photography and minimalist commercial style.",
|
|
341
|
+
enabled: true,
|
|
342
|
+
custom: false,
|
|
343
|
+
maxImages: 1,
|
|
344
|
+
waitTimeout: 50,
|
|
345
|
+
defaultImageUrls: []
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
name: "挂件化",
|
|
349
|
+
prompt: "Turn this photo into a cute charm / a flat acrylic keychain / a flat rubber keychain to hang on an LV bag / the bag in photo 2.",
|
|
350
|
+
enabled: true,
|
|
351
|
+
custom: false,
|
|
352
|
+
maxImages: 1,
|
|
353
|
+
waitTimeout: 50,
|
|
354
|
+
defaultImageUrls: []
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: "姿势表",
|
|
358
|
+
prompt: "请为这幅插图创建一个姿势表,摆出各种姿势",
|
|
359
|
+
enabled: true,
|
|
360
|
+
custom: false,
|
|
361
|
+
maxImages: 1,
|
|
362
|
+
waitTimeout: 50,
|
|
363
|
+
defaultImageUrls: []
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: "高清修复",
|
|
367
|
+
prompt: "Enhance this image to high resolution",
|
|
368
|
+
enabled: true,
|
|
369
|
+
custom: false,
|
|
370
|
+
maxImages: 1,
|
|
371
|
+
waitTimeout: 50,
|
|
372
|
+
defaultImageUrls: []
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: "人物转身",
|
|
376
|
+
prompt: "show me this scene from behind the subjects. keep the details and the lighting identical",
|
|
377
|
+
enabled: true,
|
|
378
|
+
custom: false,
|
|
379
|
+
maxImages: 1,
|
|
380
|
+
waitTimeout: 50,
|
|
381
|
+
defaultImageUrls: []
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
name: "绘画四宫格",
|
|
385
|
+
prompt: "Step 1: line drawing. Step 2: tile colors. Step 3: Add Shadows. Step 4: Refine and shape. No words",
|
|
386
|
+
enabled: true,
|
|
387
|
+
custom: false,
|
|
388
|
+
maxImages: 1,
|
|
389
|
+
waitTimeout: 50,
|
|
390
|
+
defaultImageUrls: []
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
name: "发型九宫格",
|
|
394
|
+
prompt: "A professional hairstyle showcase based on the input image of a person's upper body and face, displaying the character with nine distinct hairstyles arranged in a clean, grid-like layout (3x3 grid) on a single image. Each hairstyle replaces the original hair while preserving the person's facial features, skin tone, and clothing details from the input image. The hairstyles include a variety of styles: short pixie cut, long wavy hair, sleek bob, voluminous curls, high ponytail, messy bun, side-swept bangs, braided updo, and straight layered cut, each rendered with realistic textures and natural lighting. The background is a consistent, neutral color (pure white or light gray) to emphasize the hairstyles and maintain a polished, professional look suitable for hairstyle selection. Subtle labels beneath each hairstyle indicate the style name for clarity.",
|
|
395
|
+
enabled: true,
|
|
396
|
+
custom: false,
|
|
397
|
+
maxImages: 1,
|
|
398
|
+
waitTimeout: 50,
|
|
399
|
+
defaultImageUrls: []
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
name: "头像九宫格",
|
|
403
|
+
prompt: "Id photos of the person in the picture with 9 different hairstyles, showing close-ups of the person with each hairstyle (Japanese, Korean, n) , keeping the features and clothes, and integration of the output for a nine grid picture",
|
|
404
|
+
enabled: true,
|
|
405
|
+
custom: false,
|
|
406
|
+
maxImages: 1,
|
|
407
|
+
waitTimeout: 50,
|
|
408
|
+
defaultImageUrls: []
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
name: "表情九宫格",
|
|
412
|
+
prompt: "Transform the input person image (half-body portrait) into a 3x3 grid of nine distinct images, each showcasing a different facial expression with the corresponding text label below the face, while retaining the original character's facial features, hairstyle, and clothing details. Arrange the expressions as follows: top row (happy with raised corners and squinted eyes labeled 'Happy', sad with downturned mouth and raised inner brows labeled 'Sad', angry with furrowed brows and narrowed eyes labeled 'Angry'); middle row (surprised with wide eyes and open mouth labeled 'Surprised', fearful with wide eyes and tense brows labeled 'Fearful', disgusted with wrinkled nose and pursed lips labeled 'Disgusted'); bottom row (confused with uneven brows and asymmetrical mouth labeled 'Confused', proud with lifted chin and firm gaze labeled 'Proud', embarrassed with tense smile and downward gaze labeled 'Embarrassed'). Ensure each cell reflects the described expression naturally, with seamless completion of the lower body to match the original clothing style. Use a soft, unified background (e.g., light gray) and consistent lighting across all grids to maintain coherence and focus on the expressions.",
|
|
413
|
+
enabled: true,
|
|
414
|
+
custom: false,
|
|
415
|
+
maxImages: 1,
|
|
416
|
+
waitTimeout: 50,
|
|
417
|
+
defaultImageUrls: []
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
name: "多机位",
|
|
421
|
+
prompt: "生成这张图片的正脸特写、侧身照、远景、背影的四种多机位镜头,然后整合输出到一张照片里,保持人物高度的一致性,适合生成连续剧情感镜头",
|
|
422
|
+
enabled: true,
|
|
423
|
+
custom: false,
|
|
424
|
+
maxImages: 1,
|
|
425
|
+
waitTimeout: 50,
|
|
426
|
+
defaultImageUrls: []
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
name: "电影分镜",
|
|
430
|
+
prompt: "用这图里的角色创作一个令人上瘾的12部分故事,包含12张图像,讲述经典的黑色电影侦探故事。故事关于他们寻找线索并最终发现的失落的宝藏。整个故事充满刺激,有情感的高潮和低谷,以精彩的转折和高潮结尾。不要在图像中包含任何文字或文本,纯粹通过图像本身讲述故事",
|
|
431
|
+
enabled: true,
|
|
432
|
+
custom: false,
|
|
433
|
+
maxImages: 1,
|
|
434
|
+
waitTimeout: 50,
|
|
435
|
+
defaultImageUrls: []
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
name: "动漫分镜",
|
|
439
|
+
prompt: "According to the content of the picture to generate nine frames of comics, with pictures and lenses to tell a story.",
|
|
440
|
+
enabled: true,
|
|
441
|
+
custom: false,
|
|
442
|
+
maxImages: 1,
|
|
443
|
+
waitTimeout: 50,
|
|
444
|
+
defaultImageUrls: []
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
name: "真人化",
|
|
448
|
+
prompt: "in Studio, pure white background, a cosplayer dressed in an identical outfit, as the girl in the reference image, mimicking her pose and outfit. enhanced with film grain for a gritty, authentic particle effect reminiscent of 35mm film stock; 8K ultra-HD, sharp and believable, no abstraction.",
|
|
449
|
+
enabled: true,
|
|
450
|
+
custom: false,
|
|
451
|
+
maxImages: 1,
|
|
452
|
+
waitTimeout: 50,
|
|
453
|
+
defaultImageUrls: []
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
name: "真人化2",
|
|
457
|
+
prompt: "Generate a highly detailed photo of a girl cosplaying this illustration, at Comiket. Exactly replicate the same pose, body posture, hand gestures, facial expression, and camera framing as in the original illustration. Keep the same angle, perspective, and composition, without any deviation",
|
|
458
|
+
enabled: true,
|
|
459
|
+
custom: false,
|
|
460
|
+
maxImages: 1,
|
|
461
|
+
waitTimeout: 50,
|
|
462
|
+
defaultImageUrls: []
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
name: "半真人",
|
|
466
|
+
prompt: "Take the image of the woman in [Input Photo]. Apply a creative split-style effect. Keep the lower half of her body (legs and boots) as the original photograph. Transform the upper half of her body (torso, arms, head) into a vibrant, 2D anime style with bold outlines and flat colors, similar to the anime 'Cyberpunk: Edgerunners'. The transition between the two styles should be a clean, slightly curved line.",
|
|
467
|
+
enabled: true,
|
|
468
|
+
custom: false,
|
|
469
|
+
maxImages: 1,
|
|
470
|
+
waitTimeout: 50,
|
|
471
|
+
defaultImageUrls: []
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
name: "半融合",
|
|
475
|
+
prompt: "A striking, high-definition frontal portrait of the character from the input photo, with the face perfectly centered. The image blends two styles seamlessly: the left half retains the character's original realistic appearance, including detailed skin textures, natural lighting, and exact facial features from the input image, while the right half transitions into a vibrant manga-style version, featuring bold outlines, expressive eyes, and stylized features typical of high-quality anime art, while preserving recognizable traits (e.g., hair shape, facial structure). The transition between the realistic and manga halves is smooth and gradual, with no visible dividing line, ensuring a natural, cohesive fusion at the center of the face. The blending emphasizes the contrast between realistic and manga aesthetics while maintaining a unified appearance. The background is a neutral, solid color (e.g., soft gray or white) to highlight the fusion effect, with consistent lighting to enhance the artistic impact and no harsh separation.",
|
|
476
|
+
enabled: true,
|
|
477
|
+
custom: false,
|
|
478
|
+
maxImages: 1,
|
|
479
|
+
waitTimeout: 50,
|
|
480
|
+
defaultImageUrls: []
|
|
481
|
+
}
|
|
482
|
+
];
|
|
483
|
+
var Config = import_koishi.Schema.intersect([
|
|
484
|
+
import_koishi.Schema.object({
|
|
485
|
+
basename: import_koishi.Schema.string().default(name).description("父级指令名称"),
|
|
486
|
+
nested: import_koishi.Schema.object({
|
|
487
|
+
commands: import_koishi.Schema.array(
|
|
488
|
+
import_koishi.Schema.object({
|
|
489
|
+
name: import_koishi.Schema.string().required().description("指令名称"),
|
|
490
|
+
prompt: import_koishi.Schema.string().role("textarea", { rows: [6, 4] }).description("该指令对应的提示词(自定义指令可留空)"),
|
|
491
|
+
enabled: import_koishi.Schema.boolean().default(true).description("是否启用该指令"),
|
|
492
|
+
custom: import_koishi.Schema.boolean().default(false).description("是否为自定义指令(允许用户输入提示词)"),
|
|
493
|
+
maxImages: import_koishi.Schema.number().default(1).min(0).max(5).description("需要用户提供的最大图片数量(不包括默认图片)"),
|
|
494
|
+
waitTimeout: import_koishi.Schema.number().default(30).max(120).min(10).step(1).description("等待输入图片的最大时间(秒)"),
|
|
495
|
+
defaultImageUrls: import_koishi.Schema.array(import_koishi.Schema.string().role("link")).description("默认图片URL列表(不计入用户图片数量)").default([])
|
|
496
|
+
})
|
|
497
|
+
).description("指令配置").default(defaultCommands)
|
|
498
|
+
}).collapse().description("指令配置项太长啦,这样折叠起来更方便哦~"),
|
|
499
|
+
defaultWaitTimeout: import_koishi.Schema.number().default(50).max(120).min(10).step(1).description("默认等待输入图片的最大时间(秒)")
|
|
500
|
+
}).description("基础配置"),
|
|
501
|
+
import_koishi.Schema.object({
|
|
502
|
+
baseUrl: import_koishi.Schema.string().default("https://api.gptgod.online/v1/chat/completions").role("link").description("API 服务器地址(OpenAI 兼容 Chat Completions 接口)"),
|
|
503
|
+
model: import_koishi.Schema.string().default("gemini-2.5-flash-image").description("使用的模型名称"),
|
|
504
|
+
apiKey: import_koishi.Schema.string().role("secret").description("API 密钥"),
|
|
505
|
+
maxRetries: import_koishi.Schema.number().default(3).description("最大重试次数"),
|
|
506
|
+
retryInterval: import_koishi.Schema.number().default(1e3).description("重试间隔(毫秒)")
|
|
507
|
+
}).description("API 设置"),
|
|
508
|
+
import_koishi.Schema.object({
|
|
509
|
+
loggerinfo: import_koishi.Schema.boolean().default(false).description("日志调试模式")
|
|
510
|
+
}).description("调试设置")
|
|
511
|
+
]);
|
|
512
|
+
function apply(ctx, config) {
|
|
513
|
+
let isActive = true;
|
|
514
|
+
ctx.on("dispose", () => {
|
|
515
|
+
isActive = false;
|
|
516
|
+
});
|
|
517
|
+
ctx.on("ready", () => {
|
|
518
|
+
ctx.i18n.define("zh-CN", {
|
|
519
|
+
[name]: {
|
|
520
|
+
description: "将图片转换为特定风格",
|
|
521
|
+
messages: {
|
|
522
|
+
waitprompt: "请在{0}秒内发送一张图片...",
|
|
523
|
+
waitpromptmultiple: "请在{0}秒内发送{1}张图片...",
|
|
524
|
+
customprompt: "请在{0}秒内输入自定义提示词...",
|
|
525
|
+
invalidimage: "未检测到有效的图片,请重新发送带图片的消息",
|
|
526
|
+
processing: "正在处理图片,请稍候...",
|
|
527
|
+
failed: "图片生成失败,请稍后重试",
|
|
528
|
+
error: "处理过程中发生错误,请稍后重试",
|
|
529
|
+
needprompt: "请提供自定义提示词",
|
|
530
|
+
needimages: "请提供至少一张图片"
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
ctx.command(config.basename);
|
|
535
|
+
for (const cmdConfig of config.nested.commands) {
|
|
536
|
+
if (!cmdConfig.enabled) continue;
|
|
537
|
+
ctx.command(`${config.basename}/${cmdConfig.name} [message:text]`).usage(`使用 ${cmdConfig.name} 风格处理图片`).action(async ({ session }, message) => {
|
|
538
|
+
if (!isActive || !ctx.scope.isActive) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
if (!session) return;
|
|
542
|
+
const quote = import_koishi.h.quote(session.messageId);
|
|
543
|
+
const customCommand = cmdConfig.custom || false;
|
|
544
|
+
const maxImages = cmdConfig.maxImages || 0;
|
|
545
|
+
const waitTimeout = cmdConfig.waitTimeout || config.defaultWaitTimeout;
|
|
546
|
+
const defaultImageUrls = cmdConfig.defaultImageUrls || [];
|
|
547
|
+
let promptText = cmdConfig.prompt;
|
|
548
|
+
let images = [];
|
|
549
|
+
if (defaultImageUrls.length > 0) {
|
|
550
|
+
images.push(...defaultImageUrls);
|
|
551
|
+
logInfo(`添加 ${defaultImageUrls.length} 张默认图片`);
|
|
552
|
+
}
|
|
553
|
+
if (customCommand) {
|
|
554
|
+
let textContent;
|
|
555
|
+
if (message) {
|
|
556
|
+
const textElements = import_koishi.h.select(session.stripped.content, "text");
|
|
557
|
+
if (textElements.length > 0) {
|
|
558
|
+
textContent = textElements.map((el) => el.attrs.content || "").join(" ").trim();
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
if (textContent) {
|
|
562
|
+
promptText = cmdConfig.prompt ? `${cmdConfig.prompt}
|
|
563
|
+
|
|
564
|
+
${textContent}` : textContent;
|
|
565
|
+
}
|
|
566
|
+
if (!promptText) {
|
|
567
|
+
const [msgId] = await session.send(session.text("image-prompt.messages.customprompt", [waitTimeout]));
|
|
568
|
+
const userPrompt = await session.prompt(waitTimeout * 1e3);
|
|
569
|
+
try {
|
|
570
|
+
await session.bot.deleteMessage(session.channelId, msgId);
|
|
571
|
+
} catch {
|
|
572
|
+
ctx.logger.warn(`在频道 ${session.channelId} 尝试撤回消息ID ${msgId} 失败。`);
|
|
573
|
+
}
|
|
574
|
+
if (userPrompt) {
|
|
575
|
+
promptText = cmdConfig.prompt ? `${cmdConfig.prompt}
|
|
576
|
+
|
|
577
|
+
${userPrompt}` : userPrompt;
|
|
578
|
+
} else {
|
|
579
|
+
await session.send(`${quote}${session.text("image-prompt.messages.needprompt")}`);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const extractedImages = extractImagesFromSession(session);
|
|
585
|
+
images.push(...extractedImages);
|
|
586
|
+
const remainingImages = Math.max(0, maxImages - extractedImages.length);
|
|
587
|
+
if (remainingImages > 0) {
|
|
588
|
+
const [msgId] = await session.send(
|
|
589
|
+
session.text("image-prompt.messages.waitpromptmultiple", [waitTimeout, remainingImages])
|
|
590
|
+
);
|
|
591
|
+
try {
|
|
592
|
+
for (let i = 0; i < remainingImages; i++) {
|
|
593
|
+
const promptContent = await session.prompt(waitTimeout * 1e3);
|
|
594
|
+
if (promptContent !== void 0) {
|
|
595
|
+
const newImages = extractImagesFromMessage(promptContent);
|
|
596
|
+
images.push(...newImages);
|
|
597
|
+
} else {
|
|
598
|
+
break;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
} finally {
|
|
602
|
+
try {
|
|
603
|
+
await session.bot.deleteMessage(session.channelId, msgId);
|
|
604
|
+
} catch {
|
|
605
|
+
ctx.logger.warn(`在频道 ${session.channelId} 尝试撤回消息ID ${msgId} 失败。`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
if (images.length === 0) {
|
|
610
|
+
await session.send(`${quote}${session.text("image-prompt.messages.needimages")}`);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
logInfo(images);
|
|
614
|
+
try {
|
|
615
|
+
await session.send(quote + session.text("image-prompt.messages.processing"));
|
|
616
|
+
const files = await Promise.all(
|
|
617
|
+
images.map((src) => ctx.http.file(src).catch((err) => {
|
|
618
|
+
ctx.logger.error(`下载图片失败: ${src}`, err);
|
|
619
|
+
return null;
|
|
620
|
+
}))
|
|
621
|
+
).then((results) => results.filter(Boolean));
|
|
622
|
+
if (files.length === 0) {
|
|
623
|
+
await session.send(`${quote}${session.text("image-prompt.messages.invalidimage")}`);
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
const result = await generateFigureImage(files, promptText);
|
|
627
|
+
if (result) {
|
|
628
|
+
return import_koishi.h.image(result);
|
|
629
|
+
} else {
|
|
630
|
+
return session.text("image-prompt.messages.failed");
|
|
631
|
+
}
|
|
632
|
+
} catch (error) {
|
|
633
|
+
ctx.logger.error(`[${cmdConfig.name}] 处理图片时发生错误:`, error);
|
|
634
|
+
return session.text("image-prompt.messages.error");
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
function extractImagesFromSession(session) {
|
|
639
|
+
const images = [];
|
|
640
|
+
const currentImages = extractImagesFromMessage(session.stripped.content);
|
|
641
|
+
images.push(...currentImages);
|
|
642
|
+
if (session.quote) {
|
|
643
|
+
const quoteImages = extractImagesFromMessage(session.quote.content);
|
|
644
|
+
images.push(...quoteImages);
|
|
645
|
+
}
|
|
646
|
+
return images;
|
|
647
|
+
}
|
|
648
|
+
function extractImagesFromMessage(content) {
|
|
649
|
+
const images = [];
|
|
650
|
+
const imgElements = import_koishi.h.select(content, "img");
|
|
651
|
+
for (const img of imgElements) {
|
|
652
|
+
if (img.attrs.src) {
|
|
653
|
+
images.push(img.attrs.src);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
const mfaceElements = import_koishi.h.select(content, "mface");
|
|
657
|
+
for (const mface of mfaceElements) {
|
|
658
|
+
if (mface.attrs.url) {
|
|
659
|
+
images.push(mface.attrs.url);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return images;
|
|
663
|
+
}
|
|
664
|
+
async function generateFigureImage(files, prompt) {
|
|
665
|
+
try {
|
|
666
|
+
const dataUrls = [];
|
|
667
|
+
for (const file of files) {
|
|
668
|
+
let processedImageData = file.data;
|
|
669
|
+
let originalMimeType = file.mime || "image/jpeg";
|
|
670
|
+
let finalMimeType = originalMimeType;
|
|
671
|
+
let base64Image;
|
|
672
|
+
if (Buffer.isBuffer(processedImageData)) {
|
|
673
|
+
base64Image = processedImageData.toString("base64");
|
|
674
|
+
} else if (processedImageData instanceof ArrayBuffer) {
|
|
675
|
+
base64Image = Buffer.from(processedImageData).toString("base64");
|
|
676
|
+
} else {
|
|
677
|
+
base64Image = Buffer.from(processedImageData).toString("base64");
|
|
678
|
+
}
|
|
679
|
+
dataUrls.push(`data:${finalMimeType};base64,${base64Image}`);
|
|
680
|
+
}
|
|
681
|
+
const contentArray = [
|
|
682
|
+
{
|
|
683
|
+
type: "text",
|
|
684
|
+
text: prompt
|
|
685
|
+
}
|
|
686
|
+
];
|
|
687
|
+
for (const dataUrl of dataUrls) {
|
|
688
|
+
contentArray.push({
|
|
689
|
+
type: "image_url",
|
|
690
|
+
image_url: {
|
|
691
|
+
url: dataUrl
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
const requestBody = {
|
|
696
|
+
model: config.model,
|
|
697
|
+
messages: [
|
|
698
|
+
{
|
|
699
|
+
role: "user",
|
|
700
|
+
content: contentArray
|
|
701
|
+
}
|
|
702
|
+
],
|
|
703
|
+
max_tokens: 300,
|
|
704
|
+
n: 1
|
|
705
|
+
};
|
|
706
|
+
logInfo("请求体结构:", JSON.stringify({
|
|
707
|
+
...requestBody,
|
|
708
|
+
messages: [
|
|
709
|
+
{
|
|
710
|
+
...requestBody.messages[0],
|
|
711
|
+
content: [
|
|
712
|
+
requestBody.messages[0].content[0],
|
|
713
|
+
...requestBody.messages[0].content.slice(1).map((item, index) => {
|
|
714
|
+
const originalUrl = item.image_url.url;
|
|
715
|
+
const mimeMatch = originalUrl.match(/^data:([^;]+);base64,/);
|
|
716
|
+
const mimeType = mimeMatch ? mimeMatch[1] : "image";
|
|
717
|
+
return {
|
|
718
|
+
type: "image_url",
|
|
719
|
+
image_url: {
|
|
720
|
+
url: `data:${mimeType};base64,[${originalUrl.length} chars]`
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
})
|
|
724
|
+
]
|
|
725
|
+
}
|
|
726
|
+
]
|
|
727
|
+
}, null, 2));
|
|
728
|
+
return await sendChatRequest(requestBody);
|
|
729
|
+
} catch (error) {
|
|
730
|
+
ctx.logger.error(`生成图片时发生错误: ${error}`);
|
|
731
|
+
return null;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
async function sendChatRequest(requestBody) {
|
|
735
|
+
let retryCount = 0;
|
|
736
|
+
while (retryCount <= config.maxRetries) {
|
|
737
|
+
if (!isActive || !ctx.scope.isActive) {
|
|
738
|
+
ctx.logger.info("插件已卸载,停止重试");
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
try {
|
|
742
|
+
logInfo(`发送请求到 ${config.baseUrl},第 ${retryCount + 1} 次尝试`);
|
|
743
|
+
const headers = {
|
|
744
|
+
"Content-Type": "application/json"
|
|
745
|
+
};
|
|
746
|
+
if (config.apiKey) {
|
|
747
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
748
|
+
}
|
|
749
|
+
const response = await ctx.http.post(config.baseUrl, requestBody, { headers });
|
|
750
|
+
if (response && response.choices && response.choices[0] && response.choices[0].message) {
|
|
751
|
+
const message = response.choices[0].message;
|
|
752
|
+
logInfo(`响应:${JSON.stringify(response)}`);
|
|
753
|
+
if (message.content) {
|
|
754
|
+
const markdownMatch = message.content.match(/!\[.*?\]\((https?:\/\/[^)]+)\)/);
|
|
755
|
+
if (markdownMatch && markdownMatch[1]) {
|
|
756
|
+
const imageUrl = markdownMatch[1];
|
|
757
|
+
logInfo(`成功获取图片URL: ${imageUrl}`);
|
|
758
|
+
return imageUrl;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
const errorMsg = "响应中未找到图片URL";
|
|
763
|
+
throw new Error(errorMsg);
|
|
764
|
+
} catch (error) {
|
|
765
|
+
retryCount++;
|
|
766
|
+
const errorMessage = error.message || error.toString();
|
|
767
|
+
const statusCode = error.response?.status || 0;
|
|
768
|
+
logInfo(`请求失败 (${retryCount}/${config.maxRetries}): ${errorMessage}`);
|
|
769
|
+
if (errorMessage.includes("insufficient_quota") || statusCode === 429) {
|
|
770
|
+
ctx.logger.error("API 配额不足,停止重试");
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
if (retryCount <= config.maxRetries) {
|
|
774
|
+
logInfo(`等待 ${config.retryInterval}ms 后重试`);
|
|
775
|
+
await (0, import_koishi.sleep)(config.retryInterval);
|
|
776
|
+
if (!isActive || !ctx.scope.isActive) {
|
|
777
|
+
ctx.logger.info("插件已卸载,停止重试");
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
} else {
|
|
781
|
+
ctx.logger.error(`达到最大重试次数 (${config.maxRetries}),最后错误: ${errorMessage}`);
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return null;
|
|
787
|
+
}
|
|
788
|
+
function logInfo(...args) {
|
|
789
|
+
if (config.loggerinfo) {
|
|
790
|
+
logger.info(...args);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
796
|
+
0 && (module.exports = {
|
|
797
|
+
Config,
|
|
798
|
+
apply,
|
|
799
|
+
inject,
|
|
800
|
+
name,
|
|
801
|
+
usage
|
|
802
|
+
});
|