【问题标题】:Including base64-encoded image in ReportLab-generated PDF在 ReportLab 生成的 PDF 中包含 base64 编码的图像
【发布时间】:2012-04-16 08:21:29
【问题描述】:

我正在尝试解码 base64 编码的图像并将其放入我使用 ReportLab 生成的 PDF 中。我目前是这样做的(image_data 是 base64 编码的图像,story 已经是 ReportLab 的故事):

# There is some "story" I append every element
img_height = 1.5 * inch  # max image height
img_file = tempfile.NamedTemporaryFile(mode='wb', suffix='.png')
img_file.seek(0)
img_file.write(image_data.decode('base64'))
img_file.seek(0)
img_size = ImageReader(img_file.name).getSize()
img_ratio = img_size[0] / float(img_size[1])
img = Image(img_file.name,
    width=img_ratio * img_height,
    height=img_height,
)
story.append(img)

并且它有效(尽管在我看来仍然很难看)。我想过摆脱临时文件(不应该像文件一样的对象吗?)。

为了摆脱临时文件,我尝试使用StringIO 模块,创建类似文件的对象并传递它而不是文件名:

# There is some "story" I append every element
img_height = 1.5 * inch  # max image height
img_file = StringIO.StringIO()
img_file.seek(0)
img_file.write(image_data.decode('base64'))
img_file.seek(0)
img_size = ImageReader(img_file).getSize()
img_ratio = img_size[0] / float(img_size[1])
img = Image(img_file,
    width=img_ratio * img_height,
    height=img_height,
)
story.append(img)

但这给了我 IOError 以下消息:“无法识别图像文件”。

我知道 ReportLab 使用 PIL 来读取不同于 jpg 的图像,但是有什么方法可以避免创建命名的临时文件并且只使用类似文件的对象来执行此操作,而不将文件写入磁盘?

【问题讨论】:

    标签: python django reportlab temporary-files stringio


    【解决方案1】:

    您应该用PIL.Image.open 包装StringIO(),所以只需img_size = ImageReader(PIL.Image.open(img_file)).getSize()。正如 Tommaso 的回答所暗示的,它实际上是 Image.size 的一个薄包装。另外,其实不需要自己计算desc大小,boundreportlab.Image的模式可以帮你搞定:

    img_height = 1.5 * inch  # max image height
    img_file = StringIO.StringIO(image_data.decode('base64'))
    img_file.seek(0)
    img = Image(PIL.Image.open(img_file),
                width=float('inf'),
                height=img_height,
                kind='bound')
    )
    story.append(img)
    

    【讨论】:

      【解决方案2】:

      我不熟悉 ReportLab,但如果您可以直接使用 PIL,这将起作用:

      ...
      img = Image.open(img_file)
      width, height = img.size
      ...
      

      您可以在这里查看 PIL Image 类references

      【讨论】:

        【解决方案3】:

        此代码在没有 PIL 的情况下对我有用,因为图像已经是 JPEG: raw 只是从字典中提取 base64 字符串。我只是将解码的“字符串”包装在 StringIO 中。

                raw = element['photographs'][0]['jpeg']
                photo = base64.b64decode(raw)
                c.drawImage(ImageReader(StringIO.StringIO(photo)), 0.5*inch, self.y, height = self.PHOTOHEIGHT, preserveAspectRatio = True)
        

        【讨论】:

          【解决方案4】:

          这个解决方案对我有用。我正在将 Flask 与 Google App Engine 一起使用。

          from reportlab.platypus import Image
          from reportlab.lib.units import mm
          import cStringIO
          from base64 import b64decode
          
          story=[]
          encoded_image = "...."
          decoded_img = b64decode(encoded_image)
          img_string = cStringIO.StringIO(decoded_img)
          img_string.seek(0)
          im = Image(img_string, 180*mm, 100*mm, kind='bound')
          story.append(im)
          

          我已收到客户端发来的图片并保存在数据库中:

          from base64 import b64decode
          image = request.files['image'].read()
          encoded_image = b64encode(image)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-02-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-19
            相关资源
            最近更新 更多