是否可以使用ReportLab (python)在 PDF 中创建渐变填充?
3 回答
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()
这将输出六个页面,其中包含各种渐变以及渐变方法调用和显示端点和停止位置的线条/圆圈:
[我的答案不再正确,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)
例如。不幸的是,让渐变平滑需要很多矩形,这会导致 PDF 很大并且渲染缓慢。你最好使用光栅方法。
最后,您可能会考虑使用 PyCairo。这对许多图形元素有更好的支持,并且可以呈现为 PDF 或 PNG。但是,它缺少 reportlabs 更高级别的结构(例如页面布局)。
您想用渐变而不是纯色填充矩形(或其他路径)?
没问题。使用剪辑将渐变绑定/限制到路径。请记住在设置渐变之前设置剪辑路径。(并将其包裹在saveState()
/restoreState()
之后重置剪辑和渐变。)
c = canvas.Canvas (filename)
#c.translate (8*cm, 8*cm) # use this to move the rectangle
p = c.beginPath()
p.rect (0,0 , 5*cm,5*cm)
c.clipPath (p, stroke=0)
c.linearGradient (0,0 , 5*cm, 5*cm , (red, yellow))
extend
对于径向渐变,将关键字参数设置为 可能就足够了False
。