我有一个ipython笔记本,带有我本地驱动器的嵌入式图像。我期待它与代码单元的输出一起嵌入JSON中,但是当我分发笔记本时,图像并没有出现在用户身上。在Notebook中嵌入图像的推荐方法是什么,如果用户重新运行代码单元,清除单元格输出等,它不会消失?
笔记本系统缓存![label](image.png)
附带的图像,但它们仅持续到重启服务笔记本的python“内核”为止。如果我重命名磁盘上的图像文件,我可以关闭并重新打开笔记本,它仍然显示图像;但是当我重新启动内核时它会消失。
编辑:如果我将图像生成为代码单元输出,然后将笔记本导出为html,则图像将作为编码数据嵌入到html中。当然必须有一种方法来挂钩这个功能并将输出加载到降价(或更好的“原始nbconvert”)单元格?
from IPython.display import Image
Image(filename='imagename.png')
将导出(带ipython nbconvert
)到包含以下内容的html:
<div class="output_png output_subarea output_execute_result">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnAAAAFgCAYAAAA...
</div>
但是,即使我将此代码段手动嵌入到降价单元格中,我也无法显示该图像。我做错了什么?
PS 现有的(旧的)答案提供了一些非常有用的指针,但不是解决方案。
答案 0 :(得分:9)
您是否乐意使用额外的代码单元来显示图像?如果是这样,请使用:
from IPython.display import Image
Image(filename="example.png")
输出单元格将原始图像数据嵌入.ipynb
文件中,以便您共享它,图像将被保留。
请注意,Image
类还有一个url
关键字,但除非您同时指定embed=True
,否则只会将链接添加到图像中(请参阅{ {3}}了解详情)。因此,除非您在远程服务器上引用图像,否则使用filename
关键字会更安全。
如果您要求将图像包含在Markdown单元格中,即不需要单独的代码单元来生成嵌入的图像数据,我不确定是否有简单的解决方案。您可以使用documentation,它允许在markdown单元格中动态显示Python变量的内容。但是,扩展会动态生成markdown单元格,因此为了在共享笔记本时保留输出,您需要使用“安装”一节中提到的预处理器ipython nbconvert --to notebook original_notebook.ipynb --output preprocessed_notebook
运行pymdpreprocessor.py
。然后,生成的笔记本将数据嵌入在markdown单元格中作为<img src="data:image/png;base64,...">
格式的HTML标记,以便您可以从preprocessed_notebook.ipynb
中删除相应的代码单元格。不幸的是,当我尝试这个时,<img>
标签的内容实际上并没有显示在浏览器中,所以不确定这是否是一个可行的解决方案。 : - /
另一种选择是使用代码单元格中的Image
类来生成上面的图像,然后使用nbconvert
和自定义模板从笔记本中删除代码输入单元格。有关详细信息,请参阅python markdown extension。但是,这将从已转换的笔记本中删除所有代码单元格,因此可能不是您想要的。
答案 1 :(得分:3)
之所以
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnAAAAFgCAYAAAA...
当你把它放在降价单元格中时,标签没有做任何事情是因为IPython使用HTML清理程序(称为Google Caja)来筛选出这种类型的标记(以及许多其他标记)被渲染。
通过将以下行添加到custom.js
文件(通常位于~/.ipython/profile_default/static/custom/custom.js
),可以完全禁用IPython中的HTML清理程序:
iPython.security.sanitize_html = function (html) { return html; };
它不是一个很好的解决方案,因为它确实会产生安全风险,而且它对分发的帮助并不大。
后记:
将base64编码的字符串渲染为图像的能力!=显而易见的安全问题,因此Caja人应该有办法最终允许这种事情通过(尽管the related feature request ticket在2012年首次开放,所以不要&# 39;屏住呼吸)。
答案 2 :(得分:1)
我发现,将![name](image)
中的图片URL替换为base64 URL(类似于上面找到的URL)可以将图片嵌入markdown容器中。
降价示例:
![smile](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAD9JREFUGJW1jzEOADAIAqHx/1+mE4ltNXEpI3eJQknCIGsiHSLJB+aO/06PxOo/x2wBgKR2jCeEy0rOO6MDdzYQJRcVkl1NggAAAABJRU5ErkJggg==)
答案 3 :(得分:0)
如果使用IPython HTML()
函数输出原始HTML,则可以使用以下方法将链接的图像嵌入base64
标签内的<img>
中:
import base64
import requests
from IPython.core.display import HTML
def embedded_image(url):
response = requests.get(url)
uri = ("data:" +
response.headers['Content-Type'] + ";" +
"base64," + str(base64.b64encode(response.content).decode('utf-8')))
return uri
# Here is a small example. When you export the notebook as HTML,
# the image will be embedded in the HTML file
html = f'<img src="{embedded_image("https://upload.wikimedia.org/wikipedia/commons/5/56/Kosaciec_szczecinkowaty_Iris_setosa.jpg")}" />'
HTML(html)
更新:正如@alexis指出的那样,这实际上并不能正确回答问题,这将不允许用户重新运行单元格并保留图像(此解决方案仅允许将图像嵌入到导出文件中。
答案 4 :(得分:0)
从Jupyter Notebook 5开始,您可以将图像数据附加到单元格,并通过attachment:<image-file-name>
从单元格中引用它们。请参阅菜单Edit > Insert Image
,或使用拖放操作。
不幸的是,当将带有附加(嵌入式)图像的笔记本转换为HTML时,这些图像将不会显示。
要使它们进入HTML代码,可以使用(例如)nbtoolbelt
。
它将用嵌入在attachment:
标签中的图像数据用data:
替换那些img
引用。