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

时间:2009-01-16 21:24:13

标签: python pdf gradient reportlab

是否可以使用ReportLab(python)?

在PDF中创建渐变填充

3 个答案:

答案 0 :(得分:6)

ReportLab现在支持PDF渐变。

2012年8月6日彼得·约翰逊提供的梯度支持补丁为posted to the ReportLab mailing list,第二天为added to the source。我无法在the release notes for ReportLab 2.6中发现任何内容,但自2012年10月1日发布以来,大概是在那里。它绝对存在于2.7。

可以指定具有多个停靠点的线性和径向渐变。在文档中搜索术语 gradient 并没有出现任何问题。但是,message with the first version of the patch有几个例子是some tests in the ReportLab source的基础。基于此,我编写了一个快速演示脚本:

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()

这将输出六页不同的渐变加上渐变方法调用以及显示端点和停靠位置的线条/圆圈:

Basic linear gradient extending over page Linear gradient constrained within endpoints Linear gradient with multiple stops Basic radial gradient extending over page Radial gradient constrained within radius Radial gradient with multiple stops

答案 1 :(得分: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)

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

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

答案 2 :(得分:0)

您希望用渐变填充矩形(或其他路径)而不是 纯色?

没问题。使用裁剪将渐变限制/限制为路径。只需记住在设置渐变之前设置剪辑路径。 (然后将其包裹在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可能就足够了。