0

0

Streamlit应用:在同一文件夹下高效展示多个本地GIF图像

花韻仙語

花韻仙語

发布时间:2025-11-07 13:01:21

|

568人浏览过

|

来源于php中文网

原创

本教程详细介绍了如何在streamlit应用中,从本地指定文件夹高效展示多个gif图像。文章阐述了利用base64编码将gif文件转换为数据url,并通过st.markdown结合html Streamlit应用:在同一文件夹下高效展示多个本地GIF图像 标签嵌入显示的核心原理。同时,强调了使用glob模块进行文件查找以及正确管理文件路径(包括os.chdir)以确保跨平台兼容性和代码健壮性。

引言:在Streamlit中展示本地GIF图像的挑战

在开发Streamlit应用程序时,有时我们需要展示存储在本地文件系统中的图像,特别是动态的GIF图像。尽管Streamlit提供了st.image等组件用于显示图片,但对于需要批量展示本地GIF,或者通过自定义HTML结构进行精细控制的场景,直接使用st.image可能无法完全满足需求。一个常见的挑战是,如何将本地文件安全有效地嵌入到Web页面中,并确保路径处理在不同操作系统上都能兼容。

本文将深入探讨一种健壮且跨平台的解决方案,利用base64编码和st.markdown组件,配合Python的glob模块来批量发现并展示本地GIF文件。

核心原理:Base64编码与HTML嵌入

Web浏览器通常无法直接访问用户本地文件系统中的文件。为了在HTML中显示本地图像,我们必须将图像数据本身嵌入到HTML文档中。base64编码提供了一种将二进制数据(如图像文件)转换为ASCII字符串的方法,这个字符串可以直接作为数据URL(Data URL)嵌入到HTML的<img>标签的src属性中。

其基本格式为:data:image/gif;base64,{base64编码字符串}。

Streamlit的st.markdown组件允许我们渲染Markdown格式的内容,并且通过设置unsafe_allow_html=True参数,可以安全地嵌入自定义HTML代码。这为我们提供了将base64编码的GIF图像嵌入到Streamlit应用中的途径。

文件发现与路径管理:glob模块的应用

在处理本地文件时,正确地定位和列出文件至关重要。

为什么os.listdir可能不足

最初的尝试可能使用os.listdir()来列出文件夹内容,然后通过os.path.isfile()进行筛选。然而,os.listdir()返回的只是文件名或目录名,不包含完整的路径。如果当前工作目录不是目标文件夹,那么os.path.isfile(f)将无法正确判断文件的存在性,因为f是一个相对路径,且相对于当前工作目录,而不是目标GIF目录。

glob的优势

glob模块提供了一种更灵活的文件名模式匹配机制。glob.glob(pattern)函数可以根据指定的模式返回所有匹配的文件或目录路径列表。例如,glob.glob("*.gif")将返回当前工作目录下所有.gif文件的列表。它的优势在于:

  1. 模式匹配: 可以方便地筛选特定类型的文件。
  2. 路径处理: 当配合os.chdir()使用时,可以简化文件路径的构建。

os.chdir的重要性

在某些情况下,为了让glob.glob()能够直接使用简单的模式(如"*.gif")来匹配目标文件夹中的文件,我们需要临时改变Python脚本的当前工作目录到目标文件夹。os.chdir(path)函数可以实现这一点。改变工作目录后,glob.glob("*.gif")就会在新的工作目录中查找文件。

Cutout.Pro
Cutout.Pro

AI驱动的视觉设计平台

下载

实现步骤与代码示例

以下是实现这一功能的完整步骤和代码示例:

1. 导入必要模块

我们需要streamlit用于构建Web应用,base64用于编码GIF数据,os用于路径操作,glob用于文件查找,以及platform用于跨平台兼容性。

import streamlit as st
import base64
import os, glob
import platform

2. 动态确定GIF目录

为了使代码在Windows、Linux或macOS等不同操作系统上都能正常运行,我们需要根据当前操作系统的路径分隔符(或/)动态构建GIF文件所在的目录路径。

sys_platform = platform.system()
work_dir = os.path.dirname(os.path.abspath(__file__)) # 获取当前脚本的绝对路径

# 根据操作系统确定GIF文件夹路径
if sys_platform == "Windows":
    mypath = os.path.join(work_dir, "forecast", "fr") + "\" # Windows使用反斜杠
else:
    mypath = os.path.join(work_dir, "forecast", "fr") + "/" # Unix/Linux/macOS使用正斜杠

# 确保路径存在
if not os.path.exists(mypath):
    st.error(f"GIF目录不存在: {mypath}")
    st.stop()

3. 列出所有GIF文件

使用os.chdir()切换到GIF目录,然后使用glob.glob("*.gif")获取所有GIF文件的列表。

# 改变当前工作目录到GIF文件夹
original_cwd = os.getcwd() # 保存原始工作目录
os.chdir(mypath)

# 使用glob查找所有GIF文件
fileslist = []
for file in glob.glob("*.gif"):
    fileslist.append(file)

# 恢复原始工作目录,这是一个良好的实践
os.chdir(original_cwd)

if not fileslist:
    st.warning(f"在目录 '{mypath}' 中未找到任何GIF文件。")
    st.stop()

4. 循环展示GIF

遍历GIF文件列表,对每个文件执行以下操作:

  1. 构建完整的文件路径。
  2. 以二进制模式读取文件内容。
  3. 将内容base64编码。
  4. 构建HTML <img> 标签,并将编码后的数据作为src属性。
  5. 使用st.markdown(..., unsafe_allow_html=True)显示。
st.markdown("### 本地GIF图像展示")

for gif_filename in fileslist:
    # 确保文件路径是完整的,因为我们之前改变了工作目录,glob返回的是相对路径
    full_gif_path = os.path.join(mypath, gif_filename)

    try:
        with open(full_gif_path, "rb") as file_:
            contents = file_.read()
            data_url = base64.b64encode(contents).decode("utf-8")

        st.markdown(
            f'<img src="/uploads/20251107/1762460255690d025f55e57.gif" alt="{gif_filename}" style="max-width:100%; height:auto;">',
            unsafe_allow_html=True,
        )
        st.caption(f"显示: {gif_filename}") # 添加文件标题
    except FileNotFoundError:
        st.error(f"文件未找到: {full_gif_path}")
    except Exception as e:
        st.error(f"处理文件 '{gif_filename}' 时发生错误: {e}")

完整代码示例

将以上片段整合,形成一个完整的Streamlit应用脚本。假设你的项目结构如下:

your_streamlit_app/
├── app.py
└── forecast/
    └── fr/
        ├── gif1.gif
        ├── gif2.gif
        └── ...

其中app.py是你的Streamlit脚本。

import streamlit as st
import base64
import os, glob
import platform

# 1. 动态确定GIF目录
sys_platform = platform.system()
work_dir = os.path.dirname(os.path.abspath(__file__)) # 获取当前脚本的绝对路径

# 根据操作系统确定GIF文件夹路径
# os.path.join 是更推荐的方式来构建路径,它会自动处理分隔符
mypath = os.path.join(work_dir, "forecast", "fr")

# 确保路径存在
if not os.path.exists(mypath):
    st.error(f"GIF目录不存在: {mypath}")
    st.stop()

# 2. 列出所有GIF文件
# 保存原始工作目录,这是一个良好的实践,以便在操作完成后恢复
original_cwd = os.getcwd()
try:
    os.chdir(mypath) # 改变当前工作目录到GIF文件夹
    fileslist = [f for f in glob.glob("*.gif")]
finally:
    os.chdir(original_cwd) # 无论如何都要恢复原始工作目录

if not fileslist:
    st.warning(f"在目录 '{mypath}' 中未找到任何GIF文件。")
    st.stop()

# 3. 循环展示GIF
st.markdown("### 本地GIF图像展示")

for gif_filename in fileslist:
    full_gif_path = os.path.join(mypath, gif_filename) # 构建完整路径

    try:
        with open(full_gif_path, "rb") as file_:
            contents = file_.read()
            data_url = base64.b64encode(contents).decode("utf-8")

        st.markdown(
            f'<img src="/uploads/20251107/1762460255690d025f55e57.gif" alt="{gif_filename}" style="max-width:100%; height:auto;">',
            unsafe_allow_html=True,
        )
        st.caption(f"显示: {gif_filename}") # 添加文件标题
    except FileNotFoundError:
        st.error(f"文件未找到: {full_gif_path}")
    except Exception as e:
        st.error(f"处理文件 '{gif_filename}' 时发生错误: {e}")

关键代码解析

  • os.path.dirname(os.path.abspath(__file__)): 这行代码用于获取当前脚本文件所在的目录的绝对路径,确保无论脚本从何处运行,都能正确找到相对路径下的forecast/fr目录。
  • os.path.join(): 这是构建跨平台路径的最佳实践,它会根据当前操作系统自动选择正确的路径分隔符。
  • os.chdir(mypath) 和 os.chdir(original_cwd): 临时改变工作目录是为了让glob.glob("*.gif")能够直接在目标文件夹中查找文件。try...finally块确保即使在处理文件过程中发生错误,也能恢复到原始工作目录,保持程序的健壮性。
  • with open(full_gif_path, "rb") as file_:: 使用with语句确保文件在读取完毕后会被正确关闭,"rb"模式表示以二进制读取。
  • base64.b64encode(contents).decode("utf-8"): 将二进制文件内容编码为base64字符串,然后解码为UTF-8文本,以便嵌入到HTML中。
  • st.markdown(f'<img src="/uploads/20251107/1762460255690d025f55e57.gif" ...>', unsafe_allow_html=True): 这是将GIF图像显示到Streamlit应用的关键。unsafe_allow_html=True是必需的,因为它允许Streamlit渲染包含HTML标签的字符串。style="max-width:100%; height:auto;"可以确保图像在不同屏幕尺寸下都能自适应显示。

注意事项与最佳实践

  1. 性能考量: base64编码的图像会增加HTML文档的大小。如果GIF文件数量众多或单个文件体积较大,可能会导致页面加载缓慢或浏览器性能下降。对于大量或大型图像,考虑将它们托管到CDN或使用Streamlit的st.image直接引用URL(如果GIFs在可公开访问的路径)。
  2. 安全性提示: unsafe_allow_html=True参数允许在Streamlit应用中渲染任意HTML内容。这意味着如果你的应用处理用户输入并将其直接传递给st.markdown,可能会存在跨站脚本攻击(XSS)的风险。在本教程的场景中,我们只处理本地信任的GIF文件,风险较低,但仍需注意。
  3. 错误处理: 示例代码中加入了try...except块来捕获文件未找到或处理过程中可能发生的其他错误,这对于生产环境中的应用至关重要。
  4. 用户体验: 可以考虑添加一个加载指示器或进度条,尤其是在GIF文件较多时,提升用户体验。
  5. 文件组织: 保持GIF文件在一个独立的、结构清晰的文件夹中是一个好习惯,便于管理和维护。

总结

通过结合base64编码、st.markdown的HTML嵌入能力以及glob模块的文件发现机制,我们成功地构建了一个在Streamlit应用中高效、跨平台展示多个本地GIF图像的解决方案。这个方法不仅解决了本地文件访问的限制,还提供了灵活的展示控制。在实际应用中,请务必考虑性能和安全性因素,并根据具体需求进行优化。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

651

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1229

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1205

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

131

2025.08.07

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 10.7万人学习

Git 教程
Git 教程

共21课时 | 4.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号