Files
bigwo/parsers/image_parser.py

72 lines
2.6 KiB
Python
Raw Permalink Normal View History

"""图片文件解析器,使用 Vision API 识别图片内容"""
import base64
import os
from typing import List, Optional
from api_client import ApiClient, EXTENSION_MIME_MAP
from exceptions import ApiError, ParseError
from parsers.base import BaseParser
DEFAULT_VISION_PROMPT = """\
请识别并提取图片中的所有文字和关键信息请按以下结构输出
1. **产品/主题名称**图片展示的主要产品或主题
2. **文字内容**图片中所有可见的文字保持原始排版
3. **关键信息**成分功效用法用量规格价格等结构化信息
4. **图片描述**简要描述图片的视觉内容产品外观包装等
如果某项信息不存在可以省略该项"""
class ImageParser(BaseParser):
"""图片解析器,通过 Vision API 将图片转换为文本描述"""
def __init__(self, api_client: ApiClient, vision_prompt: Optional[str] = None):
self._api_client = api_client
self._vision_prompt = vision_prompt or DEFAULT_VISION_PROMPT
def supported_extensions(self) -> List[str]:
return [".png", ".jpg", ".jpeg", ".bmp", ".gif", ".webp"]
def parse(self, file_path: str) -> str:
"""
解析图片文件读取二进制 base64 编码 调用 Vision API 返回文本描述
会将文件名作为上下文提示传入 prompt提高识别准确度
"""
file_name = os.path.basename(file_path)
product_name = os.path.splitext(file_name)[0]
# 1. 读取图片文件
try:
with open(file_path, "rb") as f:
image_bytes = f.read()
except Exception as e:
raise ParseError(file_name, f"文件读取失败: {e}")
# 2. Base64 编码
image_base64 = base64.b64encode(image_bytes).decode("utf-8")
# 3. 根据扩展名确定 MIME 类型
ext = os.path.splitext(file_path)[1].lower()
mime_type = EXTENSION_MIME_MAP.get(ext, "image/png")
# 4. 构建带文件名上下文的 prompt
context_prompt = (
f"{self._vision_prompt}\n\n"
f"参考信息:该图片的文件名为「{product_name}」,可能与图片内容相关。"
)
# 5. 调用 Vision API
try:
result = self._api_client.vision(
system_prompt=context_prompt,
image_base64=image_base64,
mime_type=mime_type,
)
except ApiError as e:
raise ParseError(file_name, f"Vision API 调用失败: {e}")
return result