дать байтов отчету - PullRequest
       9

дать байтов отчету

1 голос
/ 06 июня 2019

Я прочитал, что вы можете использовать байты как объект для 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]

1 Ответ

0 голосов
/ 18 июня 2019

Я думаю, вы должны как-то передать buff в ImageReader.

Я использую эту функцию для сохранения и рисования фигур, которые я генерирую с помощью matplotlib, и она отлично работает для меня.

def save_and_draw(fig, x_img, y_img, width_img=width_img, height_img=height_img): 
    imgdata = BytesIO()
    fig.savefig(imgdata, format='png')
    imgdata.seek(0)
    imgdata = ImageReader(imgdata)

    self.c.drawImage(imgdata, x_img, y_img, width_img, height_img)
    plt.close(fig)
...