如何创建一个 BytesIO img 并传递给模板
How to create an BytesIO img and pass to template
目标
我正在尝试:
- 创建直方图,
- 暂存,
- 将图像传递给模板。
我在执行上述第 3 步时遇到问题。我怀疑我在将 context
数据传递给模板时犯了一个简单而根本的错误。
错误
HTML 正在使用损坏的图像标签进行渲染。
代码
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 概述的 get
和 get_context_data
问题外,另一个问题是我必须将 base64 字符串解码为 Unicode 字符串。有关详细信息,请参阅 。
为此,我包括: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}
您调用 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
中调用 get_histogram
方法,或覆盖 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
输出如下所示:
目标
我正在尝试:
- 创建直方图,
- 暂存,
- 将图像传递给模板。
我在执行上述第 3 步时遇到问题。我怀疑我在将 context
数据传递给模板时犯了一个简单而根本的错误。
错误
HTML 正在使用损坏的图像标签进行渲染。
代码
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 概述的 get
和 get_context_data
问题外,另一个问题是我必须将 base64 字符串解码为 Unicode 字符串。有关详细信息,请参阅
为此,我包括: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}
您调用 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
中调用 get_histogram
方法,或覆盖 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
输出如下所示: