【问题标题】:give a bytes to reportlab.lib.utils.ImageReader给reportlab.lib.utils.ImageReader一个字节
【发布时间】:2019-06-06 17:42:40
【问题描述】:

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

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

这是一个如何使用 BytesIO 作为ImageReader() 的输入的示例 How to draw image from raw bytes using ReportLab?

该类用于制作绘图并使用BytesIO() 将其保存到内存中。 string 是我稍后要传递的值

#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"' % name)
img = utils.ImageReader(img_path)
"OSError: 无法打开资源 "b'iVBORw0KGgoAAA' 等,

对于 Error2 我收到了

OSError: 无法识别图像文件 <_io.bytesio>
无法识别图像文件 <_io.bytesio>
fileName=<_io.bytesio object at> identity=[ImageReader@0x7f8e43fd15c0]

【问题讨论】:

    标签: python django file reportlab


    【解决方案1】:

    我认为您必须以某种方式将buff 传递给ImageReader

    我正在使用这个函数来保存和绘制我用matplotlib 生成的图形,它对我来说非常有效。

    seek(offset, whence=SEEK_SET) 将流位置更改为给定的偏移量。行为取决于 wherece 参数。 wherece 的默认值为 SEEK_SET。

    getvalue() 除了seek(0) 之外不起作用

    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)
    

    【讨论】:

    • 谢谢我遇到的问题是在错误的位置寻找,你的回答很好,谢谢。我认为我不能接受它作为正确答案,因为我没有足够的声誉。谢谢。
    • @chadmc 我很确定你可以accept it
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 2016-09-24
    • 2015-05-08
    • 1970-01-01
    相关资源
    最近更新 更多