ofa_image-caption代码实例:扩展支持WebP格式与EXIF元数据保留功能

ofa_image-caption代码实例:扩展支持WebP格式与EXIF元数据保留功能

1. 引言

你有没有遇到过这种情况?从手机或相机里导出一堆照片,想快速整理归档,却要一张张手动写描述,费时又费力。或者,在做内容创作时,需要为大量图片配上精准的英文说明,人工处理效率极低。

今天要介绍的这个工具,就是来解决这个痛点的。它叫 ofa_image-caption,是一个纯本地运行的图像描述生成工具。简单来说,你给它一张图,它就能用英文告诉你这张图里有什么。

这个工具的核心是基于一个叫 OFA 的模型,这个模型在图像描述生成领域表现很不错。我们之前发布的版本已经能很好地处理 JPG、PNG 这些常见格式了。但最近,越来越多的用户开始使用 WebP 这种更高效的图片格式,同时,很多摄影师和内容创作者也希望生成的描述能保留图片拍摄时的原始信息(比如拍摄时间、相机型号)。

所以,我们对这个工具进行了一次重要的升级。这篇文章,我就带你手把手看看,我们是如何在原有代码基础上,扩展了对 WebP 格式的支持,并实现了 EXIF 元数据的保留功能。整个过程就像给一个工具加上了两个非常实用的“配件”,让它能适应更多场景,更好用。

2. 项目回顾与升级目标

在开始动手改代码之前,我们先快速回顾一下这个工具原本是干什么的,以及我们这次想让它变得多能干。

2.1 原有工具的核心功能

这个工具本质上是一个本地化的“看图说话”小助手。它的工作流程非常清晰:

  1. 你上传一张图片(之前支持 JPG, PNG, JPEG)。
  2. 工具在后台调用 OFA 模型,这个模型是专门在 COCO 英文数据集上训练过的,所以它“说”的是英文。
  3. 工具把模型生成的英文描述,通过一个简洁的网页界面展示给你看。

整个工具基于 ModelScope 和 Streamlit 搭建,最大的优点就是纯本地运行,你的图片数据不会上传到任何服务器,隐私有保障,而且如果电脑有独立显卡(GPU),推理速度会非常快。

2.2 本次升级要解决的两个问题

随着用户增多,我们收到了两类反馈:

  1. 格式支持问题:“我有很多网站截图和素材是 WebP 格式的,上传不了,还得先转换,太麻烦了。”
  2. 信息关联问题:“生成的描述很好,但如果能和我照片自带的拍摄信息(EXIF)一起保存下来,对我后续整理和归档就太有帮助了。”

因此,我们这次代码升级的目标非常明确:

  • 目标一:让工具能直接读取和处理 WebP 格式的图片。
  • 目标二:在生成描述的同时,把图片原始的 EXIF 元数据(如果有的话)提取并保留下来,方便后续使用。

下面,我们就进入实战环节,看看代码具体是怎么改的。

3. 代码实战:扩展WebP格式支持

原来工具里,限制图片格式的代码可能长这样(在文件上传组件处):

uploaded_file = st.file_uploader( " 上传图片", type=['jpg', 'jpeg', 'png'] # 这里只定义了三种格式 ) 

看到问题了吗?type 列表里没有 webp。所以用户上传 WebP 文件时,会被直接过滤掉,根本选不中。

解决方案非常简单,只需要加一个后缀名:

uploaded_file = st.file_uploader( " 上传图片", type=['jpg', 'jpeg', 'png', 'webp'] # 新增 ‘webp’ ) 

但是,故事还没完。 Streamlit 的 file_uploader 只是前端的“门卫”,它放行了 WebP 文件。文件传到后台 Python 代码里,我们需要用 PIL(Python 图像处理库)来打开它。如果 PIL 版本太旧,可能不认识 WebP。

所以,我们需要确保开发环境和部署环境里的 PIL(或其社区维护的活跃分支 Pillow)支持 WebP。这通常不是大问题,因为现代版本的 Pillow 基本都支持。不过,为了万无一失,我们可以在项目的依赖文件(如 requirements.txt)里明确一下 Pillow 的版本。

# requirements.txt 示例 streamlit>=1.28.0 modelscope>=1.9.0 pillow>=9.0.0 # 确保使用一个较新且稳定支持WebP的版本 

这样一来,从上传到打开,整个通路就对 WebP 格式畅通无阻了。用户现在可以直接上传 .webp 文件,工具会像处理 JPG 一样处理它。

4. 代码实战:提取与保留EXIF元数据

EXIF 是嵌入在图片文件里的一串信息,就像图片的“身份证”,记录着拍摄设备、时间、光圈、快门甚至 GPS 位置等。保留这些信息对摄影爱好者、内容管理非常有价值。

4.1 如何提取EXIF信息

我们继续使用 Pillow 库。一张图片被 PIL 打开后,我们可以通过 _getexif() 方法来尝试获取其 EXIF 数据。

下面是一个简单的函数示例,我们把它加到工具的核心代码里:

from PIL import Image import PIL.ExifTags def extract_exif(image_path): """ 提取图片的EXIF元数据。 参数: image_path: 图片文件的路径。 返回: 一个字典,包含可读的EXIF标签和值;如果无EXIF或读取失败,返回空字典。 """ exif_data = {} try: img = Image.open(image_path) # 获取原始的EXIF数据 info = img._getexif() if info: # 将数字标签码转换为可读的字符串标签 for tag, value in info.items(): decoded_tag = PIL.ExifTags.TAGS.get(tag, tag) exif_data[decoded_tag] = value except Exception as e: # 记录错误或忽略(对于没有EXIF的图片是正常的) print(f"读取EXIF时出错: {e}") return exif_data 

这个函数做了几件事:

  1. 尝试用 PIL 打开图片。
  2. 调用 _getexif() 获取原始数据。
  3. 将枯燥的数字标签(如 36867)转换成我们能看懂的文字(如 DateTimeOriginal)。
  4. 把所有信息存到一个字典里返回。

4.2 如何与描述结果一起展示

光提取出来还不够,我们需要让用户看到它。一个直观的做法是,在 Streamlit 界面上生成描述后,新增一个展示区域来显示 EXIF。

假设我们原来的结果显示是这样的:

if caption: st.success("生成成功!") st.markdown(f"**生成描述:** {caption}") 

现在我们可以升级一下:

if caption: st.success("生成成功!") st.markdown(f"**生成描述:** {caption}") # 新增:提取并显示EXIF信息 exif_info = extract_exif(temp_image_path) # temp_image_path是工具保存的临时图片路径 if exif_info: with st.expander("📸 查看图片EXIF元数据"): # 用一个可折叠区域,保持界面整洁 # 展示一些最常见、最有用的EXIF字段 if 'DateTimeOriginal' in exif_info: st.text(f"拍摄时间: {exif_info['DateTimeOriginal']}") if 'Make' in exif_info and 'Model' in exif_info: st.text(f"拍摄设备: {exif_info['Make']} {exif_info['Model']}") if 'ExposureTime' in exif_info: st.text(f"曝光时间: {exif_info['ExposureTime']} 秒") if 'FNumber' in exif_info: st.text(f"光圈值: f/{exif_info['FNumber']}") if 'ISOSpeedRatings' in exif_info: st.text(f"ISO感光度: {exif_info['ISOSpeedRatings']}") # 用户可以选择查看所有EXIF数据 if st.checkbox("显示全部EXIF信息"): st.json(exif_info) # 用JSON格式美观地展示 else: st.info("此图片未包含EXIF元数据。") 

这样一来,工具在生成英文描述后,如果图片有 EXIF,用户就能一目了然地看到关键的拍摄信息,并且可以展开查看全部详情。这对于需要根据拍摄信息来分类或描述图片的用户来说,功能就完整多了。

5. 完整功能演示与效果

让我们把上面所有的代码片段组合起来,看看升级后的工具实际运行效果如何。

5.1 操作流程演示

  1. 启动工具:在命令行运行 streamlit run app.py,打开浏览器。
  2. 上传混合格式图片:你可以同时尝试上传 test.jpg, screenshot.png, 和 photo.webp。你会发现,现在所有格式都能被成功选中并上传。
  3. 生成描述与查看EXIF
    • 上传一张用单反或手机拍摄的、带有EXIF的JPG照片(比如你相机里的原图)。
    • 点击“生成描述”。稍等片刻,界面首先会弹出绿色的成功提示,并显示生成的英文描述,例如 “生成描述: a person is riding a skateboard on a street.”
    • 在描述下方,会出现一个写着 “📸 查看图片EXIF元数据” 的可点击区域。点击展开,你就能看到拍摄时间、相机型号等具体信息。
    • 如果上传的是一张从网络下载的、已剥离EXIF的PNG图片,或者是一张简单的截图,那么工具会友好地提示“此图片未包含EXIF元数据”。

5.2 升级带来的价值

通过这两项看似不大的升级,这个本地图像描述工具的能力边界得到了有效拓展:

  • 格式兼容性更强:无缝支持WebP,覆盖了更广泛的图片来源,特别是互联网内容。
  • 信息维度更丰富:从单一的“视觉内容描述”升级为“视觉内容+拍摄元数据”的复合信息输出。这使得生成的结果不再是孤立的文本,而是能与原始资产(照片)紧密关联的结构化信息。
  • 应用场景更广:对于摄影师,可以快速批量为照片库生成描述并附带拍摄参数;对于内容管理者,可以更好地对图片素材进行自动化打标和归档。

6. 总结

回顾一下我们这次对 ofa_image-caption 工具的升级之旅。整个过程就像是一次精准的“外科手术”:

  1. 诊断需求:我们发现了用户在处理 WebP 格式和需要 EXIF 信息时的痛点。
  2. 实施改造
    • 通过修改 file_uploadertype 列表,轻松扩展了 WebP 格式支持
    • 通过编写 extract_exif 函数并集成到结果展示界面,优雅地实现了 EXIF 元数据的提取与展示
  3. 验证效果:升级后的工具,在保持原有核心功能(快速、本地、英文描述)的同时,显著提升了实用性和用户体验。

这个案例也告诉我们,一个好的工具并非一成不变。围绕用户真实的使用场景,通过一些针对性的、轻量级的代码改进,就能让工具焕发新的活力,解决更实际的问题。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 ZEEKLOG星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Read more

人工智能:自然语言处理在法律领域的应用与实战

人工智能:自然语言处理在法律领域的应用与实战

人工智能:自然语言处理在法律领域的应用与实战 学习目标 💡 理解自然语言处理(NLP)在法律领域的应用场景和重要性 💡 掌握法律领域NLP应用的核心技术(如法律文本分析、案件预测、合同审查) 💡 学会使用前沿模型(如BERT、GPT-3、Transformer)进行法律文本分析 💡 理解法律领域的特殊挑战(如数据敏感性、术语标准化、实时性要求高) 💡 通过实战项目,开发一个法律文本分类应用 重点内容 * 法律领域NLP应用的主要场景 * 核心技术(法律文本分析、案件预测、合同审查) * 前沿模型(BERT、GPT-3、Transformer)在法律领域的使用 * 法律领域的特殊挑战 * 实战项目:法律文本分类应用开发 一、法律领域NLP应用的主要场景 1.1 法律文本分析 1.1.1 法律文本分析的基本概念 法律文本分析是对法律文本进行分析和处理的过程。在法律领域,法律文本分析的主要应用场景包括: * 法律条文分析:分析法律条文(如“

终极ComfyUI-BrushNet图像编辑指南:从入门到精通的AI绘画神器

终极ComfyUI-BrushNet图像编辑指南:从入门到精通的AI绘画神器 【免费下载链接】ComfyUI-BrushNetComfyUI BrushNet nodes 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-BrushNet ComfyUI-BrushNet是一套功能强大的自定义节点,为ComfyUI提供了原生实现的图像修复和编辑能力,包括BrushNet、PowerPaint和HiDiffusion等先进模型。本指南将帮助你快速掌握这个AI绘画神器,轻松实现专业级图像编辑效果。 🚀 什么是ComfyUI-BrushNet? ComfyUI-BrushNet是ComfyUI的扩展节点集,实现了多项前沿的AI图像编辑技术: * BrushNet:基于论文《BrushNet: A Plug-and-Play Image Inpainting Model with Decomposed Dual-Branch Diffusion》的图像修复模型 * PowerPaint:来自论文《A Task is Worth O

[特殊字符]阿里开源神器!一行代码让网站秒变 AI 原生应用,Page-Agent 太强了!

前言 最近发现了一个超厉害的开源项目——Page-Agent,这是阿里巴巴开源的浏览器内 GUI Agent 框架,只需要一行代码就能让你的网站秒变 AI 原生应用!今天就来给大家详细扒一扒这个神器。 什么是 Page-Agent? Page-Agent 是一个纯前端的浏览器内 GUI Agent 框架,它的核心理念是:让任何网站都能轻松集成 AI 能力,无需后端部署。 核心特点 ✅ 纯前端方案 - 无需后端服务器,直接在浏览器内运行 ✅ 支持多种 LLM - OpenAI、Claude、DeepSeek、Qwen、Gemini、Grok、Ollama、Kimi、GLM、LLaMA 等 ✅ 隐私优先 - 所有操作都在浏览器内完成,数据不会外泄 ✅ 人机协同 - 内置确认面板,用户可以实时查看和确认

论文降AIGC实测:9个免费降AI率提示词与笔灵AI降重效果对比

论文降AIGC实测:9个免费降AI率提示词与笔灵AI降重效果对比

凌晨两点,看着查重报告上那依旧居高不下的ai率,心态真的崩了。 这应该就是在这个毕业季,无数熬夜赶论文的兄弟姐妹们的真实写照。你最后可能会破罐子破摔地觉得,ai率高?这有啥的,反正我的论文确确实实就是自己写的,如果有人来问,我甚至能给我的论文背一遍! 但其实,ai率这东西,查的还真不是这文章是不是你自己写的,而是你文章里的逻辑是否过于通顺?思维是否太过顺滑?你可能会觉得有点反人类,但事实的确如此╮(╯﹏╰)╭ 为了测出最有效的法子,我拿废稿把市面上能叫得出名字的方法都试了一遍。不管你是想白嫖免费降ai率的指令,还是想找个稳妥的降ai率工具,这篇文章直接把饭喂到你嘴边。 一、 9个去AI味指令(免费方案) 先上不需要花钱的硬菜。免费降ai率工具其实就在你手边,就看你会不会用提示词。 大模型写东西有个死穴:太完美,太顺滑,像个没有感情的播音员。免费降低ai率的第一步,就是逼它说人话。 我琢磨了这9个改写指令,专治各种机器味。用法很简单:把标红段落 + 下面的提示词,扔回给AI。 👉 第一类:打碎逻辑链 提示词01(反线性叙事): 改写这段话。不要用“首先、其次、再次”