使用reportlab创建PDF文件的渐变填充

Ada*_*gen 11 python pdf gradient reportlab

是否可以使用ReportLab(python)在PDF中创建渐变填充?

Bla*_*air 6

ReportLab现在支持PDF渐变.

2012年8月6日,Peter Johnson在ReportLab邮件列表中发布了梯度支持补丁,并在第二天添加到源代码中.我无法在ReportLab 2.6的发行说明中发现任何内容,但自2012年10月1日发布以来,可能就是在那里.它绝对存在于2.7中.

可以指定具有多个停止的线性和径向渐变.在文档中搜索术语渐变并没有出现任何问题.但是,带有第一个版本补丁消息有几个例子,它们是ReportLab源代码某些测试的基础.基于此,我编写了一个快速演示脚本:

from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.colors import red, yellow, green
from reportlab.lib.units import mm

c = Canvas("gradient.pdf")

# Linear gradient with the endpoints extending over the page.
c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow))
c.drawString(5*mm, 290*mm, "c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow))")
c.line(105*mm, 200*mm, 180*mm, 100*mm)
c.showPage()

# Linear gradient constrained within the endpoints.
c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow), extend=False)
c.drawString(5*mm, 290*mm, "c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow), extend=False)")
c.line(105*mm, 200*mm, 180*mm, 100*mm)
c.showPage()

# Linear gradient with multiple stops.
c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow, green), (0, 0.8, 1), extend=False)
c.drawString(5*mm, 290*mm, "c.linearGradient(105*mm, 200*mm, 180*mm, 100*mm, (red, yellow, green), (0, 0.8, 1), extend=False)")
c.line(105*mm, 200*mm, 180*mm, 100*mm)
c.line(141*mm, 102*mm, 189*mm, 138*mm)
c.showPage()

# Radial gradient with the endpoint extending over the page.
c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow))
c.drawString(5*mm, 290*mm, "c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow))")
c.circle(105*mm, 200*mm, 60*mm)
c.showPage()

# Radial gradient constrained within the circle.
c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow), extend=False)
c.drawString(5*mm, 290*mm, "c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow), extend=False)")
c.circle(105*mm, 200*mm, 60*mm)
c.showPage()

# Radial gradient with multiple stops.
c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow, green), (0, 0.8, 1))
c.drawString(5*mm, 290*mm, "c.radialGradient(105*mm, 200*mm, 60*mm, (red, yellow, green), (0, 0.8, 1))")
c.circle(105*mm, 200*mm, 48*mm)
c.circle(105*mm, 200*mm, 60*mm)
c.showPage()

c.save()
Run Code Online (Sandbox Code Playgroud)

这将输出六页,其中包含各种渐变加上渐变方法调用以及显示端点和停靠位置的线条/圆圈:

基本线性渐变在页面上延伸 线性渐变受限于端点 具有多个停止的线性渐变 基本径向渐变在页面上延伸 径向梯度约束在半径范围内 具有多个停止的径向梯度


Ian*_*Ian 3

[我的答案不再正确,渐变现在可在 Reportlab 中使用,有关详细信息,请参阅本页上的其他答案。]

很抱歉再次提出这个问题,但我偶然发现了这个问题,但它还没有得到正确的回答。

答案是否定的,截至今天,ReportLab 的当前版本不支持渐变。不过,PDF 支持渐变。如果您查看 ReportLab 的 Canvas 类,您会发现它的许多方法都是围绕底层 PDF 代码生成的相对较小的包装器。要访问 RL 中的渐变,您需要扩展 Canvas 类并添加其他方法来生成正确的 PDF 代码。这是可行的,但显然不是微不足道的,这意味着您必须阅读 PDF 规范。

有两种选择。首先将渐变生成为光栅图像并使用它,然后通过绘制一系列不同颜色的矩形来生成渐变。

start_color = (1,0,0)
end_color = (0,1,0)
for i in range(100):
    p = i * 0.01
    canvas.setFillColorRGB(*[start_color[i]*(1.0-p)+end_color[i]*p for i in range(3)])
    canvas.rect(i, 0, 2, 100)
Run Code Online (Sandbox Code Playgroud)

例如。不幸的是,平滑渐变需要大量矩形,这可能会导致 PDF 很大并且渲染速度很慢。使用光栅方法会更好。

最后,您可以考虑使用 PyCairo。这可以更好地支持大量图形元素,并且可以渲染为 PDF 或 PNG。然而,它缺乏reportlabs 更高水平的结构(例如页面布局)。