【发布时间】:2009-01-16 21:24:12
【问题描述】:
是否可以使用ReportLab (python) 在 PDF 中创建渐变填充?
【问题讨论】:
标签: python pdf gradient reportlab
是否可以使用ReportLab (python) 在 PDF 中创建渐变填充?
【问题讨论】:
标签: python pdf gradient reportlab
ReportLab 现在支持 PDF 渐变。
2012 年 8 月 6 日,Peter Johnson 的 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()
这会输出六个页面,其中包含各种渐变以及渐变方法调用和显示端点和停止位置的线条/圆圈:
【讨论】:
[我的答案不再正确,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 可能就足够了。
【讨论】: