使用 Python、RSVG 和 Cairo 将 SVG 缩放至打印尺寸

我正在尝试使用 Python、Cairo 和 RSVG 在 Python 中打印一个动态创建的 SVG,代码如下(这是一个 Gtk 应用程序)。
这是一个特殊类型的纸张,准确来说是 147x205mm。如果我在 EOG 中打开 SVG,我可以毫不费力地打印它,但使用以下代码,它会将 SVG 渲染得太大,因此纸张上只容纳了一部分。
我想找到一种方法来告诉 RSVG/Cairo 将 SVG 缩放至打印上下文。

# 在初始化程序中:
    self.PrintSettings = Gtk.PrintSettings()
    self.PrintSettings.set_paper_width(147, Gtk.Unit.MM)
    self.PrintSettings.set_paper_height(204, Gtk.Unit.MM)

    self.PageSetup = Gtk.PageSetup()
    pageSize = Gtk.PaperSize.new_custom("bill", "Papel de factura", 147, 205, Gtk.Unit.MM)
    self.PageSetup.set_paper_size(pageSize)
    self.PageSetup.set_top_margin(0, Gtk.Unit.MM)
    self.PageSetup.set_bottom_margin(0, Gtk.Unit.MM)
    self.PageSetup.set_left_margin(0, Gtk.Unit.MM)
    self.PageSetup.set_right_margin(0, Gtk.Unit.MM)

def on_PrintButton_clicked(self, widget): 
    self.make_bill() #generates the SVG as "./temp.svg"         

    printOperation = Gtk.PrintOperation()
    printOperation.set_n_pages(1)
    printOperation.set_print_settings(self.PrintSettings)        

    printOperation.set_default_page_setup(self.PageSetup)

    printOperation.connect("draw_page", self.print_bill)
    print printOperation.run(Gtk.PrintOperationAction.PRINT_DIALOG, self)

def print_bill(self, printOperation, printContext, pageNr):    
    pageSetup = printContext.get_page_setup()
    cairoContext = printContext.get_cairo_context()
    svg = rsvg.Handle(file = os.getcwd() + "/temp.svg")
    svg.render_cairo(cairoContext)
    return

如有帮助,这是我的 SVG 开头(始终相同):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="513.77954"
height="726.37793"
id="svg2">
<defs
 id="defs4" />
<metadata
 id="metadata7">
 <rdf:RDF>
  <cc:Work
     rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type
       rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    <dc:title></dc:title>
  </cc:Work>
 </rdf:RDF>
</metadata>
<g
 transform="translate(0,-325.9842)"
 id="layer1">

更新

我在 print_bill 中添加了以下行:

    print printContext.get_width() # 返回 416.692913386
    print printContext.get_height() # 返回 581.102362205

这与 SVG 的尺寸完全相同。我在 Inkscape 中重新检查了一下,它告诉我,这是 PX 的尺寸,但如果我以毫米为单位查找值,则会显示正确的值。
也许有一个 SVG 标签可以解决这个问题?

2、解决方案

问题在于 SVG 的初始尺寸(513.77954x726.37793)与打印纸张的尺寸(147x205)不匹配。为了将 SVG 缩放至打印尺寸,需要在渲染 SVG 之前调整其大小。

以下是如何使用 cairo_scale() 函数实现此操作:

def print_bill(self, printOperation, printContext, pageNr):    
    pageSetup = printContext.get_page_setup()
    cairoContext = printContext.get_cairo_context()
    
    # 获取 SVG 的原始尺寸
    svgWidth = svg.get_width()
    svgHeight = svg.get_height()
    
    # 计算缩放比例
    scaleX = pageSetup.get_width() / svgWidth
    scaleY = pageSetup.get_height() / svgHeight
    
    # 将 SVG 缩放至打印尺寸
    cairo.scale(cairoContext, scaleX, scaleY)
    
    # 渲染 SVG
    svg.render_cairo(cairoContext)
    return

通过这种方式,SVG 将被缩放至打印纸张的尺寸,并且可以正确打印。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值