Я прочитал, что вы можете использовать байты как объект для reportlab.lib.utils.ImageReader()
. Если я читаю путь к файлу, он работает нормально, но вместо этого я хочу использовать объект, подобный байту, и таким образом я могу сохранить нужный график в памяти, и ему не нужно постоянно сохранять обновленные графики на диске.
Здесь я нашел код для преобразования изображения в строку
https://www.programcreek.com/2013/09/convert-image-to-string-in-python/
Это пример того, как использовать BytesIO в качестве ввода для ImageReader()
Как нарисовать изображение из необработанных байтов, используя ReportLab?
Этот класс используется для построения графика и передачи его в память с помощью BytesIO()
. строка - это значение, которое я собираюсь передать позже
#imports
import PyPDF2
from io import BytesIO
from reportlab.lib import utils
from reportlab.lib.pagesizes import landscape, letter
from reportlab.platypus import (Image, SimpleDocTemplate,
Paragraph, Spacer)
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch, mm
import datetime
import os
import csv
import io
import base64
import urllib
from django.contrib import admin
from django.forms import model_to_dict
from django.http import HttpResponse
from django.urls import path
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
from reporting import models, functions, functions2
import matplotlib
matplotlib.use('agg')
from matplotlib import pyplot as plt
import numpy as np
def make_plot(data):
items = [tuple(item) for item in data.items()]
keys = [item[0] for item in items]
vals = [item[1] for item in items]
fig, ax = plt.subplots()
ind = np.arange(len(keys)) # the x locations for the groups
width = 0.35 # the width of the bars
rects1 = ax.bar(ind - width/2, vals, width)
ax.set_ylabel('Count')
ax.set_xticks(ind)
ax.set_xticklabels(keys)
buf = io.BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
string = base64.b64encode(buf.read())
return 'data:image/png;base64,' + urllib.parse.quote(string), string
Это минимальный код, показывающий, как информация перемещается туда, где происходит ошибка.
class ProgressReportAdmin(ReadOnlyAdmin):
current_extra_context = None
@csrf_protect_m
def changelist_view(self, request, extra_context=None):
plot = make_plot(data)
self.current_extra_context = plot[1]
def export(self, request):
image = self.current_extra_context
pdf = functions.LandscapeMaker(image, fname, rotate=True)
pdf.save()
Здесь происходит ошибка, в функции scaleImage
class LandscapeMaker(object):
def __init__(self, image_path, filename, rotate=False):
self.pdf_file = os.path.join('.', 'media', filename)
self.logo_path = image_path
self.story = [Spacer(0, 1*inch)]
def save(self):
fileObj = BytesIO()
self.doc = SimpleDocTemplate(fileObj, pagesize=letter,
leftMargin=1*inch)
self.doc.build(self.story,
onFirstPage=self.create_pdf)
def create_pdf(self, canvas, doc):
logo = self.scaleImage(self.logo_path)
def scaleImage(self, img_path, maxSize=None):
#Error1 occurs on
img = utils.ImageReader(img_path)
img.fp.close()
#Error2
#image = BytesIO(img_path)
#img = utils.ImageReader(image)
#img.fp.close()
При ошибке1 я получаю:
повышение IOError ('Не удается открыть ресурс "% s"'% name)
img = utils.ImageReader (img_path)
"OSError: Невозможно открыть ресурс" b'iVBORw0KGgoAAA 'и т. Д.,
Для Error2 я получаю
OSError: невозможно идентифицировать файл изображения <_io.BytesIO объект в 0x7f8e4057bc50>
невозможно идентифицировать файл изображения <объект _io.BytesIO по адресу 0x7f8e4057bc50>
fileName = <_ io.BytesIO объект в 0x7f8e4057bc50> identity = [ImageReader @ 0x7f8e43fd15c0]