如何创建BytesIO img并传递给模板

时间:2018-11-03 02:27:18

标签: django django-templates django-views bytesio

AIM

我正在尝试:

  1. 创建直方图,
  2. 将其存储为临时内存,
  3. 将图像传递到模板。

我在执行上述第3步时遇到了麻烦。我怀疑我在将context数据传递到模板方面犯了一个简单而根本的错误。

错误

HTML呈现的图像标签损坏。

CODE

Views.py

class SearchResultsView(DetailView):

   ...

   def get(self, request, *args, **kwargs):
        self.get_histogram(request)
        return super(SearchResultsView, self).get(request, *args, **kwargs)


    def get_context_data(self, **kwargs):
        context = super(SearchResultsView, self).get_context_data(**kwargs)
        return context


    def get_histogram(self, request):
        """ Function to create and save histogram of Hashtag.locations """
        # create the histogram
        plt.show()
        img_in_memory = BytesIO()
        plt.savefig(img_in_memory, format="png")
        image = base64.b64encode(img_in_memory.getvalue())
        context = {'image':image}
        return context

Results.html

<img src="data:image/png;base64,{{image}}" alt="Location Histogram" />

解决方案

除了下面的@ruddra概述的getget_context_data的问题之外,另一个问题是我不得不将base64字符串解码为Unicode字符串。有关更多信息,请参见here

为此,我添加了:image = image.decode('utf8')

因此, views.py 看起来像这样:

def get_histogram(self, request):
    # draw histogram
    plt.show()
    img_in_memory = BytesIO()
    plt.savefig(img_in_memory, format="png") # save the image in memory using BytesIO
    img_in_memory.seek(0) # rewind to beginning of file
    image = base64.b64encode(img_in_memory.getvalue()) # load the bytes in the context as base64
    image = image.decode('utf8')
    return {'image':image}

1 个答案:

答案 0 :(得分:1)

您以错误的方式呼叫get_histogram。您可以这样做:

class SearchResultsView(DetailsView):
    ...

    def get_context_data(self, **kwargs):
         context = super(SearchResultsView, self).get_context_data(**kwargs)
         context.update(self.get_histogram(self.request))
         return context

您无需在get_histogram中调用get方法,也不必覆盖get方法。

更新

我尝试过这样:

 class SearchResultsView(DetailsView):
     ...

     def get_histogram(self):
         x = 2
         y = 3
         z = 2
         t= 3    
         plt.plot(x, y)
         plt.plot(z, t)
         plt.show()
         img_in_memory = io.BytesIO()  # for Python 3
         plt.savefig(img_in_memory, format="png")
         image = base64.b64encode(img_in_memory.getvalue())
         return {'image':image}

     def get_context_data(self, *args, **kwargs):
         context = super(SearchResultsView, self).get_context_data(*args, **kwargs)
         context.update(self.get_histogram())
         return context

输出看起来像这样: enter image description here