AI编程新范式:使用Claude Code辅助开发Qwen-Image-Edit-F2P应用脚本
AI编程新范式:使用Claude Code辅助开发Qwen-Image-Edit-F2P应用脚本
1. 引言
你有没有过这样的经历?脑子里有个不错的应用想法,比如想做一个能批量处理图片的自动化工具,但一想到要写代码、调接口、处理各种异常,热情就凉了半截。从想法到实现,中间隔着一条叫“编码实现”的鸿沟。
最近我在尝试用Qwen-Image-Edit-F2P这个图像编辑模型做一些有趣的应用,发现它的API功能挺强大,能实现智能抠图、背景替换、风格转换这些效果。但每次手动调用API、处理返回结果,效率实在太低。我想写个脚本把这些流程自动化,可又不想花太多时间在重复的编码工作上。
这时候我想到了Claude Code——不是那个聊天机器人,而是专门为编程设计的AI助手。它就像个坐在你旁边的编程伙伴,你告诉它你想做什么,它就能帮你写出代码,还能解释代码逻辑,甚至帮你调试错误。
这篇文章我就带你体验一下,怎么用Claude Code辅助开发一个完整的Qwen-Image-Edit-F2P应用脚本。整个过程下来,我感觉编程方式真的变了——不再是孤独地对着屏幕敲代码,而是和AI一起“结对编程”,把更多精力放在创意和逻辑设计上。
2. 环境准备与项目规划
2.1 你需要准备什么
开始之前,我们先看看需要哪些东西。其实要求不高,大部分你可能都已经有了:
- Python环境:3.8或更高版本就行。如果你还没装Python,去官网下载安装包,一路下一步就能搞定。
- 代码编辑器:VS Code、PyCharm、Sublime Text都行,选你习惯的。我用的VS Code,因为它和Claude Code配合起来比较方便。
- Claude Code访问:这个需要你有相应的使用权限。如果你还没有,可以看看相关的开发者平台。
- Qwen-Image-Edit-F2P API密钥:要调用图像编辑服务,你得先申请一个API密钥。通常去模型的官方平台注册账号就能拿到。
2.2 我们的脚本要做什么
在动手写代码之前,先想清楚脚本要完成哪些功能。我计划做一个图片批量处理工具,主要功能包括:
- 读取本地图片:能自动扫描指定文件夹里的所有图片文件
- 调用编辑API:把图片上传到Qwen-Image-Edit-F2P,按照指定指令进行编辑
- 保存处理结果:把编辑后的图片下载保存到本地
- 错误处理:万一API调用失败或者网络有问题,脚本不能直接崩溃
- 进度显示:处理大量图片时,得让用户知道进行到哪一步了
有了这个清晰的目标,我们就能更有针对性地向Claude Code提问,让它帮我们生成对应的代码。
2.3 创建项目结构
好的项目结构能让后续开发更顺利。我在本地新建了一个文件夹,里面准备放这些文件:
qwen-image-editor/
├── main.py # 主脚本文件
├── config.py # 配置文件(放API密钥)
├── requirements.txt # 依赖包列表
├── input_images/ # 存放待处理的图片
└── output_images/ # 存放处理后的图片
现在环境准备好了,目标也明确了,接下来就进入最有趣的部分——和Claude Code一起写代码。
3. 与Claude Code结对编程实战
3.1 第一次对话:搭建基础框架
我打开Claude Code,输入了第一个提示:
“我想用Python写一个脚本,调用Qwen-Image-Edit-F2P的API来编辑图片。需要能读取本地图片文件,调用API,然后保存处理后的图片。请帮我写一个基础框架。”
Claude Code几乎立刻就给出了回复。它先解释了一下大致的思路,然后给出了完整的代码:
import os
import requests
from pathlib import Path
from typing import List, Optional
class QwenImageEditor:
def __init__(self, api_key: str, base_url: str = "https://api.example.com/v1"):
"""
初始化图像编辑器
Args:
api_key: Qwen-Image-Edit-F2P的API密钥
base_url: API基础地址
"""
self.api_key = api_key
self.base_url = base_url
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
def edit_image(self, image_path: str, instruction: str) -> Optional[bytes]:
"""
编辑单张图片
Args:
image_path: 图片文件路径
instruction: 编辑指令,比如“换背景为白色”“调整亮度”
Returns:
编辑后的图片二进制数据,失败时返回None
"""
try:
# 读取图片文件
with open(image_path, 'rb') as f:
image_data = f.read()
# 准备请求数据
payload = {
"image": image_data,
"instruction": instruction,
"model": "qwen-image-edit-f2p"
}
# 调用API
response = requests.post(
f"{self.base_url}/images/edit",
headers=self.headers,
json=payload,
timeout=30
)
if response.status_code == 200:
return response.content
else:
print(f"API调用失败: {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"处理图片时出错: {e}")
return None
def save_image(self, image_data: bytes, output_path: str):
"""
保存图片到本地
Args:
image_data: 图片二进制数据
output_path: 保存路径
"""
with open(output_path, 'wb') as f:
f.write(image_data)
print(f"图片已保存: {output_path}")
# 使用示例
if __name__ == "__main__":
# 从配置文件读取API密钥
API_KEY = "your_api_key_here"
editor = QwenImageEditor(API_KEY)
# 编辑单张图片
result = editor.edit_image("input_images/example.jpg", "换背景为纯白色")
if result:
editor.save_image(result, "output_images/edited_example.jpg")
这段代码已经相当完整了,但我发现几个可以改进的地方。首先,API调用部分可能需要根据Qwen-Image-Edit-F2P的实际接口调整。其次,错误处理可以更细致一些。
3.2 第二次对话:完善批量处理功能
单张图片处理还不够,我需要批量处理功能。于是我又问Claude Code:
“上面的代码只能处理单张图片。现在我需要批量处理一个文件夹里的所有图片,支持常见的图片格式(jpg、png、webp),并且要显示处理进度。请帮我扩展这个功能。”
Claude Code这次给出了更详细的实现:
import os
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm # 进度条库
class BatchImageEditor(QwenImageEditor):
def __init__(self, api_key: str, base_url: str = "https://api.example.com/v1"):
super().__init__(api_key, base_url)
self.supported_formats = {'.jpg', '.jpeg', '.png', '.webp', '.bmp'}
def get_image_files(self, folder_path: str) -> List[str]:
"""
获取文件夹中所有支持的图片文件
Args:
folder_path: 文件夹路径
Returns:
图片文件路径列表
"""
image_files = []
folder = Path(folder_path)
if not folder.exists():
print(f"文件夹不存在: {folder_path}")
return image_files
for file_path in folder.iterdir():
if file_path.suffix.lower() in self.supported_formats:
image_files.append(str(file_path))
print(f"找到 {len(image_files)} 张图片")
return image_files
def process_single_image(self, image_path: str, instruction: str, output_dir: str) -> bool:
"""
处理单张图片并保存
Args:
image_path: 图片路径
instruction: 编辑指令
output_dir: 输出目录
Returns:
处理是否成功
"""
try:
# 生成输出文件名
input_file = Path(image_path)
output_filename = f"edited_{input_file.stem}{input_file.suffix}"
output_path = Path(output_dir) / output_filename
# 调用父类方法编辑图片
edited_image = self.edit_image(image_path, instruction)
if edited_image:
self.save_image(edited_image, str(output_path))
return True
else:
print(f"处理失败: {image_path}")
return False
except Exception as e:
print(f"处理图片时出错 {image_path}: {e}")
return False
def process_folder(self, input_folder: str, output_folder: str, instruction: str,
max_workers: int = 3):
"""
批量处理文件夹中的所有图片
Args:
input_folder: 输入文件夹路径
output_folder: 输出文件夹路径
instruction: 编辑指令
max_workers: 最大并发数(避免API限流)
"""
# 创建输出文件夹
os.makedirs(output_folder, exist_ok=True)
# 获取所有图片文件
image_files = self.get_image_files(input_folder)
if not image_files:
print("没有找到可处理的图片")
return
print(f"开始批量处理 {len(image_files)} 张图片...")
print(f"编辑指令: {instruction}")
# 使用进度条
successful = 0
failed = 0
with tqdm(total=len(image_files), desc="处理进度") as pbar:
# 使用线程池并发处理
with ThreadPoolExecutor(max_workers=max_workers) as executor:
# 提交所有任务
future_to_file = {
executor.submit(self.process_single_image, img, instruction, output_folder): img
for img in image_files
}
# 处理完成的任务
for future in as_completed(future_to_file):
image_file = future_to_file[future]
try:
success = future.result()
if success:
successful += 1
else:
failed += 1
except Exception as e:
print(f"任务执行出错 {image_file}: {e}")
failed += 1
pbar.update(1)
pbar.set_postfix({"成功": successful, "失败": failed})
print(f"\n处理完成!成功: {successful}, 失败: {failed}")
# 避免频繁调用API,添加延迟
time.sleep(1)
# 使用示例
if __name__ == "__main__":
# 安装进度条库:pip install tqdm
API_KEY = "your_api_key_here"
editor = BatchImageEditor(API_KEY)
# 批量处理图片
editor.process_folder(
input_folder="input_images",
output_folder="output_images",
instruction="智能抠图,背景透明化",
max_workers=2 # 保守一点,避免触发API限流
)
这段代码加了很多实用功能:自动识别图片格式、进度显示、并发处理。Claude Code还贴心地提醒我要安装tqdm库来显示进度条。
3.3 第三次对话:添加配置文件和错误处理
现在基础功能都有了,但API密钥硬编码在代码里不安全,错误处理也可以更完善。我继续向Claude Code提问:
“请帮我添加配置文件功能,把API密钥和其他设置放到config.py里。另外,需要更完善的错误处理,包括网络重试、API限流处理、无效图片跳过等。”
Claude Code给出了配置文件和增强错误处理的方案:
首先创建config.py:
# config.py - 配置文件
# Qwen-Image-Edit-F2P API配置
QWEN_API_KEY = "your_actual_api_key_here" # 替换为你的真实API密钥
QWEN_BASE_URL = "https://api.example.com/v1" # 根据实际API地址修改
QWEN_TIMEOUT = 30 # 请求超时时间(秒)
# 图片处理配置
SUPPORTED_FORMATS = ['.jpg', '.jpeg', '.png', '.webp', '.bmp', '.gif']
MAX_FILE_SIZE_MB = 10 # 最大文件大小(MB)
DEFAULT_INSTRUCTION = "智能优化图片质量" # 默认编辑指令
# 并发和重试配置
MAX_WORKERS = 3 # 最大并发数
MAX_RETRIES = 3 # 失败重试次数
RETRY_DELAY = 2 # 重试延迟(秒)
# 路径配置
DEFAULT_INPUT_FOLDER = "input_images"
DEFAULT_OUTPUT_FOLDER = "output_images"
然后更新主脚本,加入重试机制和更健壮的错误处理:
import json
import time
from datetime import datetime
import config
class RobustImageEditor(BatchImageEditor):
def __init__(self):
super().__init__(config.QWEN_API_KEY, config.QWEN_BASE_URL)
self.max_retries = config.MAX_RETRIES
self.retry_delay = config.RETRY_DELAY
self.error_log = []
def edit_image_with_retry(self, image_path: str, instruction: str) -> Optional[bytes]:
"""
带重试机制的图片编辑
Args:
image_path: 图片路径
instruction: 编辑指令
Returns:
编辑后的图片数据,失败时返回None
"""
for attempt in range(self.max_retries):
try:
# 检查文件大小
file_size_mb = os.path.getsize(image_path) / (1024 * 1024)
if file_size_mb > config.MAX_FILE_SIZE_MB:
error_msg = f"文件过大: {image_path} ({file_size_mb:.1f}MB > {config.MAX_FILE_SIZE_MB}MB)"
print(error_msg)
self.error_log.append({
"file": image_path,
"error": error_msg,
"time": datetime.now().isoformat()
})
return None
# 调用API
result = self.edit_image(image_path, instruction)
if result:
return result
else:
if attempt < self.max_retries - 1:
wait_time = self.retry_delay * (attempt + 1)
print(f"第{attempt + 1}次尝试失败,{wait_time}秒后重试...")
time.sleep(wait_time)
else:
error_msg = f"达到最大重试次数仍失败: {image_path}"
print(error_msg)
self.error_log.append({
"file": image_path,
"error": error_msg,
"time": datetime.now().isoformat()
})
except requests.exceptions.Timeout:
if attempt < self.max_retries - 1:
wait_time = self.retry_delay * (attempt + 1)
print(f"请求超时,{wait_time}秒后重试...")
time.sleep(wait_time)
else:
error_msg = f"请求超时,达到最大重试次数: {image_path}"
print(error_msg)
self.error_log.append({
"file": image_path,
"error": error_msg,
"time": datetime.now().isoformat()
})
except Exception as e:
error_msg = f"处理图片时发生错误 {image_path}: {str(e)}"
print(error_msg)
self.error_log.append({
"file": image_path,
"error": error_msg,
"time": datetime.now().isoformat()
})
return None
return None
def save_error_log(self, log_file: str = "error_log.json"):
"""保存错误日志到文件"""
if self.error_log:
with open(log_file, 'w', encoding='utf-8') as f:
json.dump(self.error_log, f, ensure_ascii=False, indent=2)
print(f"错误日志已保存到: {log_file}")
def process_folder_robust(self, input_folder: str = None, output_folder: str = None,
instruction: str = None):
"""
健壮的批量处理流程
Args:
input_folder: 输入文件夹,默认为配置中的路径
output_folder: 输出文件夹,默认为配置中的路径
instruction: 编辑指令,默认为配置中的指令
"""
# 使用默认值
input_folder = input_folder or config.DEFAULT_INPUT_FOLDER
output_folder = output_folder or config.DEFAULT_OUTPUT_FOLDER
instruction = instruction or config.DEFAULT_INSTRUCTION
print("=" * 50)
print("Qwen图像批量处理工具")
print(f"输入文件夹: {input_folder}")
print(f"输出文件夹: {output_folder}")
print(f"编辑指令: {instruction}")
print("=" * 50)
# 检查文件夹
if not os.path.exists(input_folder):
print(f"错误: 输入文件夹不存在 - {input_folder}")
return
# 创建输出文件夹
os.makedirs(output_folder, exist_ok=True)
# 清空错误日志
self.error_log = []
# 批量处理
self.process_folder(input_folder, output_folder, instruction, config.MAX_WORKERS)
# 保存错误日志
self.save_error_log()
print("处理完成!")
# 主程序入口
def main():
"""主函数"""
print("Qwen图像编辑脚本启动...")
# 创建编辑器实例
editor = RobustImageEditor()
# 开始处理
editor.process_folder_robust()
print("程序执行完毕")
if __name__ == "__main__":
main()
现在这个脚本已经相当完善了。Claude Code不仅帮我写了代码,还解释了为什么要这样设计:配置文件让设置更灵活,重试机制提高了稳定性,错误日志方便后续排查问题。
4. 实际运行与调试
4.1 安装依赖和准备环境
代码写好了,但要运行起来还需要一些准备工作。Claude Code提醒我需要安装几个Python库:
# 创建requirements.txt文件
echo "requests>=2.28.0
tqdm>=4.64.0
pathlib>=1.0.1" > requirements.txt
# 安装依赖
pip install -r requirements.txt
然后需要准备好config.py文件,填入真实的API密钥和接口地址。Claude Code还提醒我:
“记得在运行前创建input_images文件夹,并放入一些测试图片。输出文件夹output_images会自动创建。建议先用一两张图片测试,确保API调用正常后再进行批量处理。”
4.2 测试运行
我放了几张图片到input_images文件夹,然后运行脚本:
python main.py
第一次运行就遇到了问题——API返回了认证错误。我把错误信息复制给Claude Code:
“运行脚本时出现错误:{'error': 'Invalid API key'}。我的API密钥在config.py里设置的是正确的,这是什么问题?”
Claude Code很快给出了排查建议:
- 检查API密钥是否有空格或换行
- 确认API基础地址是否正确
- 尝试用curl命令直接测试API
- 检查网络连接和防火墙设置
我按照建议检查,发现是base_url设置错了。修正之后,脚本成功运行起来,看着进度条一点点前进,图片一张张被处理,那种感觉真的很棒。
4.3 处理常见问题
在测试过程中,我还遇到了几个其他问题:
问题1:有些图片处理特别慢 Claude Code建议我添加超时设置和并发控制,避免同时处理太多图片。
问题2:API返回了尺寸限制错误 Claude Code帮我添加了文件大小检查,自动跳过过大的图片。
问题3:输出图片格式不一致 有些图片处理后格式变了,Claude Code建议在保存时统一格式,或者保留原始格式。
经过几轮调试,脚本变得越来越稳定。Claude Code在这个过程中就像个不知疲倦的编程伙伴,随时帮我分析问题、修改代码。
5. 扩展功能与优化建议
5.1 添加更多实用功能
基础功能稳定后,我想让脚本更强大一些。我又向Claude Code提了几个需求:
需求1:支持不同的编辑模式
“Qwen-Image-Edit-F2P应该支持多种编辑模式,比如抠图、背景替换、风格转换等。请帮我扩展脚本,让用户可以选择不同的模式。”
Claude Code给出了一个灵活的方案:
# 在config.py中添加
EDIT_MODES = {
"remove_bg": "智能抠图,背景透明化",
"replace_bg": "替换背景为纯色",
"enhance": "智能增强图片质量",
"cartoon": "转换为卡通风格",
"sketch": "转换为素描风格"
}
# 在主脚本中添加模式选择
def interactive_mode():
"""交互式模式"""
print("请选择编辑模式:")
for i, (mode, desc) in enumerate(config.EDIT_MODES.items(), 1):
print(f"{i}. {desc} ({mode})")
choice = input("\n请输入模式编号(1-5): ").strip()
mode_mapping = list(config.EDIT_MODES.keys())
if choice.isdigit() and 1 <= int(choice) <= len(mode_mapping):
selected_mode = mode_mapping[int(choice) - 1]
instruction = config.EDIT_MODES[selected_mode]
# 询问是否使用自定义指令
custom = input(f"使用默认指令 '{instruction}'?(y/n): ").lower()
if custom == 'n':
instruction = input("请输入自定义编辑指令: ").strip()
return instruction
else:
print("无效选择,使用默认模式")
return config.DEFAULT_INSTRUCTION
需求2:添加图片预览功能
“处理前后如果能有个对比预览就好了,不用每次都打开文件夹查看。”
Claude Code建议可以生成HTML报告:
def generate_html_report(input_folder: str, output_folder: str):
"""生成HTML格式的处理报告"""
html_content = """
<!DOCTYPE html>
<html>
<head>
<title>图片处理报告</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
.image-pair { border: 1px solid #ddd; padding: 10px; border-radius: 5px; }
.image-pair img { max-width: 100%; height: auto; }
.caption { text-align: center; margin-top: 5px; color: #666; }
</style>
</head>
<body>
<h1>图片处理报告</h1>
<p>生成时间: {timestamp}</p>
<div class="image-grid">
"""
# 收集图片对
image_pairs = []
for img_file in os.listdir(input_folder):
if img_file.lower().endswith(('.jpg', '.jpeg', '.png', '.webp')):
input_path = os.path.join(input_folder, img_file)
output_path = os.path.join(output_folder, f"edited_{img_file}")
if os.path.exists(output_path):
image_pairs.append((img_file, input_path, output_path))
# 添加图片对到HTML
for filename, input_path, output_path in image_pairs:
html_content += f"""
<div class="image-pair">
<div>
<img src="{input_path}" alt="原图">
<div class="caption">原图: {filename}</div>
</div>
<div>
<img src="{output_path}" alt="处理后">
<div class="caption">处理后: edited_{filename}</div>
</div>
</div>
"""
html_content += """
</div>
</body>
</html>
"""
# 添加时间戳
from datetime import datetime
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
html_content = html_content.format(timestamp=timestamp)
# 保存HTML文件
report_path = os.path.join(output_folder, "processing_report.html")
with open(report_path, 'w', encoding='utf-8') as f:
f.write(html_content)
print(f"处理报告已生成: {report_path}")
return report_path
5.2 性能优化建议
Claude Code还主动给出了一些优化建议:
- 缓存机制:对相同的图片和指令,可以缓存处理结果,避免重复调用API
- 批量请求:如果API支持,可以一次上传多张图片,减少网络请求次数
- 本地预处理:一些简单的操作(如调整尺寸、格式转换)可以在本地完成,减少API调用
- 异步处理:使用asyncio实现真正的异步处理,提高吞吐量
这些建议让我看到了脚本进一步优化的方向。虽然当前版本已经能满足基本需求,但有了这些思路,未来可以做得更好。
6. 总结
和Claude Code一起开发这个Qwen图像编辑脚本的过程,让我对AI辅助编程有了新的认识。以前写这种工具脚本,从设计到调试至少得花一两天时间,这次只用了几个小时就完成了核心功能。
最大的感受是,Claude Code不仅仅是个代码生成器,它更像是个经验丰富的编程搭档。它能理解我的意图,给出合理的实现方案,还能在我遇到问题时提供排查思路。我不再需要反复搜索文档、在Stack Overflow上找答案,大部分问题都能通过对话解决。
这个脚本现在虽然简单,但已经具备了生产可用的基础:健壮的错误处理、进度显示、批量并发、配置管理。更重要的是,整个开发过程很顺畅,我可以把精力集中在功能设计上,而不是语法细节上。
如果你也想尝试AI辅助编程,我的建议是:先从一个小项目开始,明确需求,然后一步步和AI对话完善。不要指望AI一次性能给出完美代码,而是要把它当作思考伙伴,通过多次迭代让代码越来越好用。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)