首页 > 解决方案 > Kivy:任意比例的 export_to_png()

问题描述

有没有办法在 Kivy 中以任意比例将小部件导出为 png?

据我了解,现在默认情况下,导出图像的比例相对于我在屏幕上看到的小部件大小为 1:1。

但是如果我想导出到 1:10(并获得 10 倍大的图像)怎么办?

对如何做到这一点的任何想法感兴趣。

标签: exportkivyscale

解决方案


我不知道做同样事情的直接方法,但你可以派生Widget 类的export_to_png方法

这是一个工作示例:

from kivy.uix.widget import Widget
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.graphics import (Canvas, Translate, Fbo, ClearColor,
                           ClearBuffers, Scale)


kv='''
BoxLayout:
    orientation: 'vertical'
    MyWidget:
        id: wgt
    BoxLayout:
        size_hint_y: .1
        orientation: 'horizontal'
        Label:
            text: 'enter scale:'
        TextInput:
            id: txtinpt
            text: '2.5'
        Button:
            text: 'Export with new scale'
            on_release: wgt.export_scaled_png('kvwgt.png', image_scale=float(txtinpt.text))

<MyWidget>:
    canvas:
        PushMatrix:
        Color:
            rgba: (0, 0, 1, .75)
        Ellipse:
            pos: (self.x + self.width // 5, self.y + self.height // 5)
            size: (self.width * 3 // 5, self.height * 3 // 5)
        Color:
            rgba: (1, 0, 0, .5)
        Rectangle:
            pos: (self.x + self.width // 4, self.y + self.height // 4)
            size: (self.width // 2, self.height // 2)
        Rotate:
            origin:
                self.center
            angle:
                45
    Button:
        text: 'useless child widget\\njust for demonstration'
        center: root.center
        size: (root.width // 2, root.height // 8)
        canvas:
            PopMatrix:

'''

class MyWidget(Widget):

    def export_scaled_png(self, filename, image_scale=1):
        re_size = (self.width * image_scale, 
                self.height * image_scale)

        if self.parent is not None:
            canvas_parent_index = self.parent.canvas.indexof(self.canvas)
            if canvas_parent_index > -1:
                self.parent.canvas.remove(self.canvas)

        fbo = Fbo(size=re_size, with_stencilbuffer=True)

        with fbo:
            ClearColor(0, 0, 0, 0)
            ClearBuffers()
            Scale(image_scale, -image_scale, image_scale)
            Translate(-self.x, -self.y - self.height, 0)

        fbo.add(self.canvas)
        fbo.draw()
        fbo.texture.save(filename, flipped=False)
        fbo.remove(self.canvas)

        if self.parent is not None and canvas_parent_index > -1:
            self.parent.canvas.insert(canvas_parent_index, self.canvas)



runTouchApp(Builder.load_string(kv))

注意 re_size 变量,它又传递给 Fbo 构造函数。以及 export_scaled_png 方法中的“ Scale(image_scale, -image_scale, image_scale) ”指令。


推荐阅读