将Gtk.DrawingArea或Cairo模式的内容保存到磁盘上的图像

发布于 2021-01-29 15:01:53

我有一个小的PyGI项目,它使用开罗图像表面,然后使用表面图案缩放并在Gtk.DrawingArea上进行渲染。

我想将 缩放后的
版本写入PNG文件。我尝试使用Surface.write_to_png()从原始表面进行写操作,但是它仅以原始(即非缩放)大小进行写操作,因此我被困在那里。

然后我想我也许可以从Gtk.DrawingArea中获取渲染的图像并将其写入磁盘,但是我还没有找到如何在PyGI中做到这一点(这似乎仅在GTK +
2中可行-将gtk.DrawingArea保存到文件)。因此,我试图弄清楚如何将缩放后的图像写入磁盘。

这是创建曲面,放大并渲染的代码:

def on_drawingarea1_draw (self, widget, ctx, data=None):

    # 'widget' is a Gtk.DrawingArea
    # 'ctx' is the Cairo context

    text = self.ui.entry1.get_text()
    if text == '':
        return

    # Get the data and encode it into the image
    version, size, im = qrencode.encode(text)
    im = im.convert('RGBA') # Cairo expects RGB

    # Create a pixel array from the PIL image
    bytearr = array.array('B', im.tostring())
    height, width = im.size

    # Convert the PIL image to a Cairo surface
    self.surface = cairo.ImageSurface.create_for_data(bytearr,
                                                 cairo.FORMAT_ARGB32,
                                                 width, height,
                                                 width * 4)

    # Scale the image
    imgpat = cairo.SurfacePattern(self.surface)

    scaler = cairo.Matrix()
    scaler.scale(1.0/self.scale_factor, 1.0/self.scale_factor)
    imgpat.set_matrix(scaler)
    ctx.set_source(imgpat)

    # Render the image
    ctx.paint()

这是将表面写入PNG文件的代码:

def on_toolbuttonSave_clicked(self, widget, data=None):
    if not self.surface:
        return

    # The following two lines did not seem to work
    # ctx = cairo.Context(self.surface)
    # ctx.scale(self.scale_factor, self.scale_factor)

    self.surface.write_to_png('/tmp/test.png')

因此,写入表面会创建非缩放图像,并且cairo.SurfacePattern中也没有写入方法。

我的最后一招是获取在gtk.DrawingArea中渲染的缩放图像,将其放在GtkPixbuf.Pixbuf或新的表面中,然后将其写入磁盘。pixbuf方法似乎适用于GTK
+ 2,但不适用于GTK + 3。

那么有人知道我如何将缩放后的图像写入磁盘吗?

关注者
0
被浏览
201
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    好的,我找到了一种方法:

    记住, Gtk.DrawingArea 派生自 Gtk.Window
    ,我可以使用Gdk.pixbuf_get_from_window()函数来获取绘图区域的内容制作成 GdkPixbuf.Pixbuf
    ,然后使用GdkPixbuf.Pixbuf.savev()函数写的pixbuf在磁盘上的图像。

    def drawing_area_write(self):
        # drawingarea1 is a Gtk.DrawingArea
        window = self.ui.drawingarea1.get_window()
    
        # Some code to get the coordinates for the image, which is centered in the
        # in the drawing area. You can ignore it for the purpose of this example
        src_x, src_y = self.get_centered_coordinates(self.ui.drawingarea1,
                                                     self.surface)
        image_height = self.surface.get_height() * self.scale_factor
        image_width = self.surface.get_width() * self.scale_factor
    
        # Fetch what we rendered on the drawing area into a pixbuf
        pixbuf = Gdk.pixbuf_get_from_window(window, src_x, src_y,
                                          image_width, image_height)
    
        # Write the pixbuf as a PNG image to disk
        pixbuf.savev('/tmp/testimage.png', 'png', [], [])
    

    在此方法奏效的同时,仍然很高兴看到有人可以确认这是正确的方法,还是看看是否还有其他选择。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看