pdf-generation - 如何防止 cairo 栅格化我的图案填充?

标签 pdf-generation vector-graphics cairo rasterizing pycairo

2011 年左右的某个时候,我编写了一个 Pycairo 脚本来生成一个 PDF,其中包含多个自定义矢量图案的填充。今天我重新运行它(Python 3.5.2,Pycairo 1.10.0),并惊讶地发现所有这些图案都被渲染为低分辨率光栅化位图。我将脚本简化为这个最小的示例:

#!/usr/bin/python3

import cairo

def main():
    surface = cairo.PDFSurface("test.pdf", 100, 100)
    ctx = cairo.Context(surface)
    pattern = make_pattern()
    ctx.rectangle(10, 10, 80, 80)
    ctx.set_source(pattern)
    ctx.fill()
    surface.finish()

def make_pattern():
    pattern_surface = cairo.PDFSurface(None, 32, 8)
    ctx = cairo.Context(pattern_surface)
    ctx.set_line_width(.5)
    ctx.set_source_rgb(0,0,0)
    ctx.move_to(5, 6)
    ctx.line_to(27, 2)
    ctx.stroke()
    pattern = cairo.SurfacePattern(pattern_surface)
    pattern.set_extend(cairo.EXTEND_REPEAT)
    return pattern

if __name__ == "__main__":
    main()

生成的 PDF 经过大幅缩放后,呈现的图案如下:

script output

观察 PDF 文件的文本可确认这是位图。使用 SVGSurface 会产生类似的结果。有没有办法恢复到旧的行为,即 PDF 图案填充在最终 PDF 中呈现为矢量填充,而不是像这样进行光栅化?我在网上找到的关于该问题的唯一引用是 this unanswered question on the cairo mailing list从 2012 年 1 月开始。

最佳答案

我仍然没有找到严格使用 Pycairo 执行此操作的方法,但我找到了使用 cairocffi 的解决方案,Pycairo 的改进版、直接替代品。 cairocffi 提供类(class) RecordingSurface ,

a surface that records all drawing operations at the highest level of the surface backend interface, (that is, the level of paint, mask, stroke, fill, and show_text_glyphs). The recording surface can then be “replayed” against any target surface by using it as a source surface.

我修改了脚本以使用 cairocffi 和 RecordingSurface:

#!/usr/bin/python3

import cairocffi as cairo

def main():
    surface = cairo.PDFSurface("test.pdf", 100, 100)
    ctx = cairo.Context(surface)
    pattern = make_pattern()
    ctx.rectangle(10, 10, 80, 80)
    ctx.set_source(pattern)
    ctx.fill()
    surface.finish()

def make_pattern():
    pattern_surface = \
        cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 32, 8))
    ctx = cairo.Context(pattern_surface)
    ctx.set_line_width(.5)
    ctx.set_source_rgb(0,0,0)
    ctx.move_to(5, 6)
    ctx.line_to(27, 2)
    ctx.stroke()
    pattern = cairo.SurfacePattern(pattern_surface)
    pattern.set_extend(cairo.EXTEND_REPEAT)
    return pattern

if __name__ == "__main__":
    main()

这导致了非光栅化图案:

script output

关于pdf-generation - 如何防止 cairo 栅格化我的图案填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54868972/

相关文章:

ruby-on-rails - Prawn table 列中的从下到上的文本

c# - 为什么 .NET 的 itext 7 使用比 itextsharp 5(多)多的内存?

java - Jasper 报告 PDF 不带汉字

android - 从 psd 清空生成的矢量文件

Haskell/Stack/Nix 构建失败,需要 pkg-config >= 0.9.0 和 cairo >= 1.2.0,但最新版本是 pkg-config 0.29.2 和 cairo 1.15.4

php - 检测api访问密码保护区

svg - 是否可以通过命令行将 Inkscape 自动跟踪 PNG 转换为 SVG?

c++ - 3D vector 归一化问题

c - Xscreensaver 代码给出 BadMatch 错误

python - 如何使用 igraph 在 python 中绘制 3d 图?