如何在 django 模板中显示保存的、动态创建的图像?

Posted

技术标签:

【中文标题】如何在 django 模板中显示保存的、动态创建的图像?【英文标题】:How to display a saved,dynamically created image in django template? 【发布时间】:2017-11-27 12:09:48 【问题描述】:

我在视图中创建了一个图,并将该图保存为模板文件夹中的 png。但是,当我尝试在模板 html 文件中使用 <img> 标记显示此保存的图像时,图像不会显示。 这是我的文件夹结构的图像: Folder Structure

这就是我将绘图保存在视图中的方式:

def result(request):
    if request.POST and request.FILES:
        mycsv=pd.read_csv(request.FILES['csv_file'])
        c=mycsv.X
        #We divide by the class height(basically) so that Xi+1-Xi=1
        x = [d / 5 for d in c]
        n=len(x)
        b=mycsv.Y
        divi=np.sum(b)
        f = [e / divi for e in b] 
        #Thus sum(f)=1, makes calculation of mean simpler

        #PLOTTING BEGINS
        fig = plt.figure()
        ax = plt.subplot(111)
        ax.plot(x, f)
        plt.title('Pearson Type 1 ')
        ax.legend()
        #plt.show()
        fig.savefig('polls/templates/polls/plot.png')
        context = 'n':n,
        return render(request, 'polls/result.html', context)
    else:
        return HttpResponse("Form Not Submitted")

我尝试获取图像的 result.html 文件是:

<h1>Graph with n points</h1>
<img src='./plot.png' />

我在本地主机上运行它,权限有问题吗?

我刚开始学习 django,想测试一下这个东西。感谢您的帮助!

【问题讨论】:

【参考方案1】:

您的方法有很多问题,但我会尝试就如何继续向您提供一些建议,尽管您可能需要重新考虑。

首先,将您的文件保存到模板目录不会使其可用于您的模板。 templates 目录是一个特殊的配置,允许你使用 Django 的模板加载器,它不会像你的图像那样加载静态文件。

您可以将图像保存到静态文件并使用 % static % 模板标签来恢复它,但是,这将是错误的方法,因为您的图像不是静态内容,它是动态创建。

由于创建后图像中的数据没有任何用处,我的建议是使用TempFile 将图像存储在临时文件中,或者使用StringIO 将图像存储在内存中(如果足够轻),然后将上下文中的这些字节加载为 base64

from StringIO import StringIO
import base64

img_in_memory = StringIO()
fig.savefig(img_in_memory, format="png") #dunno if your library can do that.
context['image'] = base64.b64encode(img_in_memory.getvalue())

然后,在您的模板中,您将执行以下操作:

<img src="data:image/png;base64,image" />

【讨论】:

谢谢,我明白了,但现在它在这行 fig.savefig(img_in_memory, format="image/png") 中给出了一个错误,因为 ValueError 和状态,不支持格式“image/png”。支持的格式:eps、jpeg、jpg、pdf、pgf、png、ps、raw、rgba、svg、svgz、tif、tiff。 我编辑了我的答案,您只需要删除该字符串的image/ 部分 我试过了,它给出了一个类型错误,搜索它,发现我要使用 StringIO.StringIO() 而不是 io.StringIO() 。然后它在 context 行中出现了一些错误,将其重写为 image=base64.b64encode(img_in_memory.getvalue()) 然后 context='image':image 。现在它起作用了!感谢您的帮助。 我将根据您的反馈进行编辑以供后代使用,不客气!【参考方案2】:

或者干脆把图片转成字符串

with open(original_image_path, "rb") as img_file:
    base64_img = base64.b64encode(img_file.read()).decode('utf-8')
    mimetype = mimetypes.guess_type(original_image_path)[0]

一旦完成,将这个变量在 HTML 上呈现为

<img src="data: mimetype ;base64, base64_img "/>

它将同时处理 jpeg 和 png。

【讨论】:

以上是关于如何在 django 模板中显示保存的、动态创建的图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 模板中显示当前年份?

如何使用 django 在模板中显示默认值?

使用 Django,如何在模板中动态设置 ModelForm 字段值?

没有在 html 模板 django 中显示模型值

我如何在 django 的同一视图功能中将最近保存的数据发送到模板中

在 Django 中,如何使用模板和 DB 对象中使用的动态 URL 实现样板 HTML 变量?