丹青识画实战教程:Python调用API实现批量图片题跋生成与PDF导出
1. 学习目标与前置准备
本教程将手把手教你如何使用Python调用丹青识画API,实现批量图片的智能题跋生成,并将结果导出为精美的PDF文档。学完本教程后,你将能够:
- 掌握丹青识画API的基本调用方法
- 编写Python脚本实现批量图片处理
- 将生成的题跋内容整理为格式化的PDF文档
- 在实际项目中应用这项技术提升工作效率
前置知识要求:只需要基础的Python编程经验,不需要深度学习或美术背景。我们将从最基础的API调用开始讲解,确保小白也能轻松上手。
2. 环境准备与API配置
2.1 安装必要的Python库
首先确保你的Python环境版本在3.7以上,然后安装以下必要的库:
pip install requests pillow reportlab这三个库的作用分别是:
requests:用于发送HTTP请求调用APIpillow:用于处理图片文件reportlab:用于生成PDF文档
2.2 获取API访问密钥
要使用丹青识画服务,你需要先注册账号并获取API密钥:
- 访问丹青识画官方网站
- 注册开发者账号
- 在控制台创建新的应用
- 获取你的API Key和Secret
将密钥信息保存在安全的地方,我们将在代码中使用它们。
3. 基础API调用方法
3.1 单张图片题跋生成
让我们先从最简单的单张图片处理开始:
import requests import base64 import json def generate_inscription(api_key, image_path): # 读取图片并编码为base64 with open(image_path, "rb") as image_file: image_data = base64.b64encode(image_file.read()).decode('utf-8') # 构建API请求 url = "https://api.danqing.shihua/v1/generate" headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } payload = { "image": image_data, "style": "calligraphy", # 书法风格 "format": "text" # 返回文本格式 } # 发送请求 response = requests.post(url, headers=headers, json=payload) if response.status_code == 200: result = response.json() return result['inscription'] else: raise Exception(f"API调用失败: {response.status_code}") # 使用示例 api_key = "你的API密钥" image_path = "test.jpg" try: inscription = generate_inscription(api_key, image_path) print("生成的题跋:", inscription) except Exception as e: print(f"错误: {e}")这段代码完成了图片读取、base64编码、API请求发送和结果处理的全过程。你可以替换image_path为你的图片路径进行测试。
3.2 处理不同类型的图片
丹青识画API支持多种图片格式和风格参数:
# 高级调用示例 def advanced_generate(api_key, image_path, style="calligraphy", detail_level="high"): with open(image_path, "rb") as f: image_data = base64.b64encode(f.read()).decode('utf-8') payload = { "image": image_data, "style": style, # 可选: calligraphy, poetry, simple "detail_level": detail_level, # 可选: low, medium, high "max_length": 200 # 最大生成长度 } response = requests.post( "https://api.danqing.shihua/v1/generate", headers={"Authorization": f"Bearer {api_key}"}, json=payload ) return response.json()4. 批量处理实战教程
4.1 批量处理图片脚本
现在我们来编写批量处理多张图片的完整脚本:
import os import time from pathlib import Path def batch_process_images(api_key, input_folder, output_file="results.txt"): """ 批量处理文件夹中的所有图片 """ # 支持的图片格式 supported_formats = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff'] # 获取所有图片文件 image_files = [] for format in supported_formats: image_files.extend(Path(input_folder).glob(f"*{format}")) image_files.extend(Path(input_folder).glob(f"*{format.upper()}")) results = [] for i, image_path in enumerate(image_files): print(f"处理第 {i+1}/{len(image_files)} 张图片: {image_path.name}") try: inscription = generate_inscription(api_key, str(image_path)) results.append({ "filename": image_path.name, "inscription": inscription, "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") }) # 避免频繁调用,添加短暂延迟 time.sleep(0.5) except Exception as e: print(f"处理 {image_path.name} 时出错: {e}") results.append({ "filename": image_path.name, "error": str(e), "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") }) # 保存结果 with open(output_file, 'w', encoding='utf-8') as f: for result in results: if 'inscription' in result: f.write(f"图片: {result['filename']}\n") f.write(f"题跋: {result['inscription']}\n") f.write(f"时间: {result['timestamp']}\n") f.write("-" * 50 + "\n") else: f.write(f"图片: {result['filename']} - 错误: {result['error']}\n") return results # 使用示例 api_key = "你的API密钥" input_folder = "path/to/your/images" results = batch_process_images(api_key, input_folder)4.2 错误处理与重试机制
在实际批量处理中,网络波动或API限制可能导致失败,我们需要添加重试机制:
def robust_generate_inscription(api_key, image_path, max_retries=3): """ 带重试机制的API调用 """ for attempt in range(max_retries): try: return generate_inscription(api_key, image_path) except Exception as e: if attempt == max_retries - 1: raise e print(f"第{attempt+1}次尝试失败,等待重试...") time.sleep(2 ** attempt) # 指数退避5. PDF导出功能实现
5.1 创建美观的PDF文档
使用reportlab库将题跋结果导出为PDF:
from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import mm from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image from reportlab.lib.utils import ImageReader def create_pdf_report(results, output_pdf="inscriptions_report.pdf"): """ 创建题跋报告PDF """ doc = SimpleDocTemplate(output_pdf, pagesize=A4) styles = getSampleStyleSheet() # 自定义样式 title_style = ParagraphStyle( 'CustomTitle', parent=styles['Heading1'], fontSize=16, spaceAfter=30, alignment=1 # 居中 ) content_style = ParagraphStyle( 'CustomContent', parent=styles['BodyText'], fontSize=11, spaceAfter=12, leading=14 ) story = [] # 添加标题 story.append(Paragraph("丹青识画 - 题跋生成报告", title_style)) story.append(Spacer(1, 20)) # 添加每个图片的题跋 for result in results: if 'inscription' in result: # 图片文件名 story.append(Paragraph(f"<b>图片:</b> {result['filename']}", content_style)) # 题跋内容 story.append(Paragraph(f"<b>题跋:</b> {result['inscription']}", content_style)) # 时间戳 story.append(Paragraph(f"<b>时间:</b> {result['timestamp']}", content_style)) story.append(Spacer(1, 15)) # 生成PDF doc.build(story) print(f"PDF报告已生成: {output_pdf}") # 使用示例 create_pdf_report(results)5.2 高级PDF美化功能
如果你想要更精美的PDF输出,可以添加更多样式:
def create_beautiful_pdf(results, output_pdf="beautiful_inscriptions.pdf"): from reportlab.lib.colors import HexColor doc = SimpleDocTemplate(output_pdf, pagesize=A4) styles = getSampleStyleSheet() # 更精美的样式 beautiful_style = ParagraphStyle( 'BeautifulStyle', parent=styles['BodyText'], fontSize=12, textColor=HexColor('#333333'), backColor=HexColor('#FFFFEF'), borderColor=HexColor('#DDDDDD'), borderWidth=1, borderPadding=10, spaceAfter=15 ) story = [] # 添加精美标题 title = Paragraph( "<font color='#8B4513' size=18>丹青识画 · 墨香雅集</font>", ParagraphStyle('Title', alignment=1) ) story.append(title) story.append(Spacer(1, 25)) # 添加内容 for result in results: if 'inscription' in result: content = f""" <b><font color='#8B4513'>〖{result['filename']}〗</font></b><br/> {result['inscription']}<br/> <font color='#888888' size=9>{result['timestamp']}</font> """ story.append(Paragraph(content, beautiful_style)) doc.build(story)6. 完整实战示例
6.1 端到端的批量处理脚本
下面是一个完整的脚本,包含所有功能:
import os import time import requests import base64 from pathlib import Path from reportlab.lib.pagesizes import A4 from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle class DanqingProcessor: def __init__(self, api_key): self.api_key = api_key self.api_url = "https://api.danqing.shihua/v1/generate" def process_single_image(self, image_path): """处理单张图片""" try: with open(image_path, "rb") as f: image_data = base64.b64encode(f.read()).decode('utf-8') response = requests.post( self.api_url, headers={"Authorization": f"Bearer {self.api_key}"}, json={"image": image_data, "style": "calligraphy"} ) if response.status_code == 200: return response.json().get('inscription', '') else: return f"API错误: {response.status_code}" except Exception as e: return f"处理错误: {str(e)}" def process_batch(self, input_folder, output_txt="results.txt", output_pdf="report.pdf"): """批量处理并生成报告""" image_files = list(Path(input_folder).glob('*.[jJ][pP][gG]')) + \ list(Path(input_folder).glob('*.[pP][nN][gG]')) results = [] for img_path in image_files: print(f"处理: {img_path.name}") inscription = self.process_single_image(img_path) results.append({ 'filename': img_path.name, 'inscription': inscription, 'timestamp': time.strftime("%Y-%m-%d %H:%M") }) time.sleep(0.5) # 避免频繁调用 # 保存文本结果 with open(output_txt, 'w', encoding='utf-8') as f: for res in results: f.write(f"{res['filename']}: {res['inscription']}\n") # 生成PDF报告 self.generate_pdf(results, output_pdf) return results def generate_pdf(self, results, output_pdf): """生成PDF报告""" doc = SimpleDocTemplate(output_pdf, pagesize=A4) styles = getSampleStyleSheet() story = [] story.append(Paragraph("丹青识画批量处理报告", styles['Heading1'])) story.append(Spacer(1, 20)) for res in results: content = f""" <b>{res['filename']}</b><br/> {res['inscription']}<br/> <i>{res['timestamp']}</i> """ story.append(Paragraph(content, styles['BodyText'])) story.append(Spacer(1, 10)) doc.build(story) # 使用示例 if __name__ == "__main__": processor = DanqingProcessor("你的API密钥") results = processor.process_batch( input_folder="你的图片文件夹路径", output_txt="题跋结果.txt", output_pdf="题跋报告.pdf" ) print("处理完成!")7. 实用技巧与注意事项
7.1 性能优化建议
- 并发处理:如果需要处理大量图片,可以使用多线程(但注意API的速率限制)
- 图片预处理:调整图片大小到合适尺寸(建议最长边不超过2000像素)
- 错误日志:添加详细的日志记录,便于排查问题
7.2 常见问题解决
- API调用限制:丹青识画API可能有调用频率限制,建议添加适当的延迟
- 图片格式问题:确保图片格式受支持,损坏的图片会导致处理失败
- 网络问题:添加重试机制处理临时的网络波动
7.3 最佳实践
- 先用小批量图片测试脚本是否正常工作
- 定期备份处理结果
- 根据实际需求调整PDF的样式和格式
- 考虑添加进度显示,便于监控长时间的处理任务
8. 总结回顾
通过本教程,我们完整学习了如何使用Python调用丹青识画API实现批量图片题跋生成和PDF导出。关键知识点包括:
- API基础调用:学会了如何准备图片数据、发送请求和处理响应
- 批量处理:掌握了遍历文件夹、处理多文件的方法
- PDF导出:使用reportlab库创建美观的报告文档
- 错误处理:添加了重试机制和异常处理,提高脚本的健壮性
这个技术可以应用于很多实际场景,比如:
- 为摄影作品批量添加艺术描述
- 为数字画展生成自动化解说
- 为文创产品制作特色标签
- 个人照片集的艺术化整理
下一步学习建议:
- 尝试集成到Web应用中,制作在线题跋生成工具
- 探索更多样式参数,生成不同风格的题跋
- 结合其他AI服务,打造更丰富的创作流程
希望本教程能帮助你快速上手丹青识画API,在实际项目中发挥创意,创作出更多有趣的应用!
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。