【问题标题】:How can I prevent cairo from rasterizing my pattern fills?如何防止 cairo 栅格化我的图案填充?
【发布时间】:2019-02-25 14:59:06
【问题描述】:

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 放大后呈现如下图案:

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

【问题讨论】:

    标签: pdf-generation vector-graphics cairo rasterizing pycairo


    【解决方案1】:

    我仍然没有找到严格使用 Pycairo 执行此操作的方法,但我找到了使用 cairocffi 的解决方案,这是 Pycairo 的一种改进的直接替代品。 cairocffi 提供课程RecordingSurface

    一个surface,记录了surface后端接口最高层的所有绘图操作,(即paint、mask、stroke、fill和show_text_glyphs的级别)。然后可以通过将记录表面用作源表面来针对任何目标表面“重放”。

    我修改了脚本以使用 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()
    

    这导致了非光栅化模式:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-21
      • 2013-08-18
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 2017-02-23
      • 1970-01-01
      相关资源
      最近更新 更多