返回 VideoClaw
image_dashscope.py
根目录 / video-claw / video-claw / backend / models / image_dashscope.py
1 import os
2 import sys
3
4 models_dir = os.path.dirname(os.path.abspath(__file__))
5 backend_dir = os.path.dirname(models_dir)
6 if backend_dir not in sys.path:
7 sys.path.insert(0, backend_dir)
8
9 import json
10 import logging
11 import time
12 import uuid
13 import dashscope
14 from dashscope import MultiModalConversation
15 from dashscope.aigc.image_generation import ImageGeneration
16 from config import Config
17 try:
18 from models.image_processor import ImageProcessor
19 except ImportError:
20 from image_processor import ImageProcessor
21
22 class DashScopeClient:
23 def __init__(self, api_key=None, base_url=None):
24 self.api_key = api_key or Config.DASHSCOPE_API_KEY
25 # 默认使用中国(北京)地域 API,如果参数或 config.yaml 未设置则使用默认地址
26 self.base_url = base_url or Config.DASHSCOPE_BASE_URL
27 dashscope.api_key = self.api_key
28 dashscope.base_http_api_url = self.base_url
29 self.image_processor = ImageProcessor()
30
31 def generate_image(self, prompt, model="wan2.7-image", size="1024*1024", n=1, session_id=None, save_dir=None):
32 """
33 Text to Image generation using DashScope
34 """
35 try:
36 messages = [{"role": "user", "content": [{"text": prompt}]}]
37 response = ImageGeneration.call(
38 model=model,
39 api_key=self.api_key,
40 messages=messages,
41 n=n,
42 size=size,
43 watermark=False,
44 )
45
46 if response.status_code == 200:
47 results = []
48 try:
49 # 标准 ImageGeneration 返回结果解析
50 if response.output and response.output.choices:
51 for item in response.output.choices:
52 if 'message' in item and 'content' in item['message']:
53 results.append(item['message']['content'][0]['image'])
54 except Exception as e:
55 logging.error(f"Failed to parse ImageGeneration outputs: {e}")
56
57 # Check if we should download
58 if save_dir:
59 os.makedirs(save_dir, exist_ok=True)
60 local_files = []
61 for i, url in enumerate(results):
62 file_name = f"ds_{session_id if session_id else 'nosess'}_{int(time.time())}_{i}_{uuid.uuid4().hex[:6]}.png"
63 file_path = os.path.join(save_dir, file_name)
64 if self.image_processor.download_image(url, file_path, proxies=Config.requests_proxies("dashscope")):
65 local_files.append(file_path)
66 return local_files
67
68 return results
69 else:
70 error_msg = f"{response.code}, {response.message}, status={response.status_code}"
71 logging.error(f"Image generation failed: {error_msg}")
72 raise RuntimeError(error_msg)
73 except Exception as e:
74 logging.error(f"Error in generate_image (DashScope): {e}")
75 raise
76
77 def edit_image(self, prompt, image_urls, model="wan2.7-image", size="1920*1080", n=1, session_id=None, save_dir=None):
78 """
79 Image editing/compositing using DashScope ImageGeneration
80 """
81 # Prepare content
82 content_list = []
83 for img_url in image_urls:
84 content_list.append({"image": img_url})
85 content_list.append({"text": prompt})
86
87 messages = [
88 {
89 "role": "user",
90 "content": content_list
91 }
92 ]
93
94 try:
95 # Use ImageGeneration.call with messages, same as generate_image
96 response = ImageGeneration.call(
97 model=model,
98 api_key=self.api_key,
99 messages=messages,
100 n=n,
101 size=size,
102 watermark=False,
103 )
104
105 if response.status_code == 200:
106 results = []
107 try:
108 # 标准 ImageGeneration 返回结果解析
109 if response.output and response.output.choices:
110 for item in response.output.choices:
111 # 简化解析逻辑以处理多张图片的返回结构
112 if isinstance(item, dict):
113 if 'image' in item: # 部分新模型直接返回 {'image': 'url', 'finish_reason': ...}
114 results.append(item['image'])
115 elif 'url' in item:
116 results.append(item['url'])
117 elif 'message' in item and 'content' in item['message']: # 兼容 Message 结构
118 content = item['message']['content']
119 if isinstance(content, list):
120 for c in content:
121 if isinstance(c, dict) and 'image' in c:
122 results.append(c['image'])
123 except Exception as e:
124 logging.error(f"Failed to parse ImageGeneration outputs: {e}")
125
126 # Check if we should download
127 if save_dir:
128 os.makedirs(save_dir, exist_ok=True)
129 local_files = []
130 for i, url in enumerate(results):
131 file_name = f"ds_{session_id if session_id else 'nosess'}_{int(time.time())}_{i}_{uuid.uuid4().hex[:6]}.png"
132 file_path = os.path.join(save_dir, file_name)
133 if self.image_processor.download_image(url, file_path, proxies=Config.requests_proxies("dashscope")):
134 local_files.append(file_path)
135 return local_files
136
137 return results
138 else:
139 error_msg = f"{response.code}, {response.message}, status={response.status_code}"
140 logging.error(f"Image edit failed: {error_msg}")
141 raise RuntimeError(error_msg)
142 except Exception as e:
143 logging.error(f"Error in edit_image: {e}")
144 raise
145
146
147 if __name__ == "__main__":
148 import sys
149 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
150 from config import Config
151
152 print("=== DashScope 图片生成可用性测试 ===")
153 MODELS=["wan2.6-t2i", "wan2.7-image", "wan2.7-image-pro"]
154 save_dir = "code/result/image/test_avail"
155 api_key = Config.DASHSCOPE_API_KEY
156 base_url = Config.DASHSCOPE_BASE_URL
157 if not api_key:
158 print("✗ DASHSCOPE_API_KEY 未设置,跳过")
159 sys.exit(1)
160 print(f" API Key: {api_key[:6]}***{api_key[-4:]}")
161 print(f" Base URL: {base_url}")
162 client = DashScopeClient(api_key=api_key, base_url=base_url)
163
164 # 文生图
165 print("\n=== 文生图测试 ===")
166 prompt = "一只橘猫躺在阳光下的窗台上,水彩画风格"
167 for model in MODELS:
168 print(f"\nPrompt: {prompt}")
169 print(f"model: {model}")
170 os.makedirs(save_dir, exist_ok=True)
171 t0 = time.time()
172 try:
173 paths = client.generate_image(
174 prompt=prompt, model=model,
175 size="1024*1024", save_dir=save_dir,
176 )
177 elapsed = time.time() - t0
178 if paths:
179 print(f"✓ 生成 {len(paths)} 张图片 ({elapsed:.1f}s): {paths}")
180 else:
181 print(f"✗ 返回空列表 ({elapsed:.1f}s)")
182 except Exception as e:
183 print(f"✗ 失败: {e}")
184 sys.exit(1)
185
186 # 图生图
187 print("\n=== 图生图测试 ===")
188 img_path = "code/result/image/test_avail/test_input.png"
189 prompt = "在这张图片的基础上,添加一些飞舞的樱花花瓣,绘制为水彩画风格"
190 for model in MODELS:
191 print(f"\nPrompt: {prompt}")
192 print(f"model: {model}")
193 os.makedirs(save_dir, exist_ok=True)
194 t0 = time.time()
195 try:
196 paths = client.edit_image(
197 prompt=prompt, image_urls=[img_path], model=model,
198 size="1024*1024", save_dir=save_dir,
199 )
200 elapsed = time.time() - t0
201 if paths:
202 print(f"✓ 生成 {len(paths)} 张图片 ({elapsed:.1f}s): {paths}")
203 else:
204 print(f"✗ 返回空列表 ({elapsed:.1f}s)")
205 except Exception as e:
206 print(f"✗ 失败: {e}")
207 sys.exit(1)
208
208 lines PYTHON