我读过您可以对reportlab.lib.utils.ImageReader()使用类似object的字节。如果我在文件路径中读取它可以正常工作,但是我想使用类似字节的对象来代替,这样我可以将所需的绘图保存在内存中,而不必经常在驱动器上保存更新的绘图。

在这里找到了将图像转换为字符串的代码
https://www.programcreek.com/2013/09/convert-image-to-string-in-python/

这是如何将BytesIO用作ImageReader()输入的示例
How to draw image from raw bytes using 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()


对于Error1,我收到:


  引发IOError('无法打开资源“%s”'%名称)
  img = utils.ImageReader(img_path)
  “ OSError:无法打开资源” b'iVBORw0KGgoAAA“等,


对于Error2我收到


  OSError:无法识别图像文件
  无法识别图像文件
  fileName = 身份= [ImageReader @ 0x7f8e43fd15c0]

最佳答案

我认为您必须以某种方式将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)

关于python - 给reportlab.lib.utils.ImageReader一个字节,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56482630/

10-12 18:19