将Gtk.DrawingArea或Cairo模式的内容保存到磁盘上的映像中 [英] Save the contents of a Gtk.DrawingArea or Cairo pattern to an image on disk

查看:221
本文介绍了将Gtk.DrawingArea或Cairo模式的内容保存到磁盘上的映像中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小型的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'是一个Gtk.DrawingArea
#'ctx'是开罗语境

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

#获取数据并将其编码到图像中
version,size,im = qrencode.encode(text)
im = im.convert('RGBA')#开罗期望RGB

#从PIL图像创建一个像素数组
bytearr = array.array('B',im。 tostring())
height,width = im.size

#将PIL图像转换为开罗表面
self.surface = cairo.ImageSurface.create_for_data(bytearr,
cairo.FORMAT_ARGB32,
宽度,高度,
宽度* 4)

#缩放图像
imgpat = cairo.SurfacePattern(self.surface)

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

#渲染图像
ctx.paint()

以下是编写代码的代码表面到PNG文件:

  def on_toolbuttonSave_clicked(self,widget,data = None):
如果不是self.surface:
返回

#以下两行似乎不起作用
#ctx = cairo.Context(self.surface)
#ctx.scale(self.scale_factor,self.scale_factor)

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

所以写表面创建一个n未缩放的图像,并且cairo.SurfacePattern也没有写入方法。



我最后的手段是获取缩放图像,在gtk.DrawingArea ,把它放在GtkPixbuf.Pixbuf或新的表面上,然后写入磁盘。 pixbuf的方法似乎可以在GTK + 2中运行,但在GTK + 3中不能运行。

所以有人知道我可以如何将缩放图像写入磁盘吗?$ / $>

解决方案

好吧,我找到了一个方法:



记住 Gtk.DrawingArea 源自 Gtk.Window ,我可以使用 Gdk.pixbuf_get_from_window()函数将绘图区域的内容变为 GdkPixbuf.Pixbuf ,然后使用 GdkPixbuf.Pixbuf.savev()函数将pixbuf作为磁盘上的映像写入。

def drawing_area_write(self):
#drawingarea1是一个Gtk。 DrawingArea
window = self.ui.drawingarea1.get_window()

#获取图像坐标的一些代码,它以图纸区域中的
#为中心。你可以忽略它,这个例子的目的
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

#将我们在绘图区域呈现的内容转换为pixbuf
pixbuf = Gdk.pixbuf_get_from_window(窗口,src_x,src_y,
image_width,image_height)

#将pixbuf作为PNG图像写入磁盘
pixbuf.savev('/ tmp / testimage.png',' png',[],[])

虽然这可行,但仍然很高兴看到如果有人能确认这是正确的方式,或者看看是否有其他选择。

I've got a small PyGI project which uses a Cairo image surface, which I then scale with a surface pattern and render on a Gtk.DrawingArea.

I'd like to write the scaled version to a PNG file. I've tried to write from the original surface with Surface.write_to_png(), but it only writes in the original (i.e. non-scaled) size, so I'm stuck in there.

Then I thought I could perhaps fetch the rendered image from the Gtk.DrawingArea and write that to disk, but I haven't found out how to do that in PyGI (this seems to be only possible in GTK+ 2 - save gtk.DrawingArea to file). So I'm trying to figure out how I can write my scaled image to disk.

Here's the code that creates the surface, scales it up and renders it:

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()

And here's the code to write the surface to a PNG file:

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')

So writing the surface creates an non-scaled image, and there is no write method in the cairo.SurfacePattern either.

My last resort is to fetch the scaled image as rendered in the gtk.DrawingArea, put it in a GtkPixbuf.Pixbuf or in a new surface, and then write that to disk. The pixbuf approach seemed to work in GTK+ 2, but not in GTK+ 3.

So does anyone know how I can write the scaled image to disk?

解决方案

Ok, I found a way:

Remembering that Gtk.DrawingArea derives from Gtk.Window, I could use the Gdk.pixbuf_get_from_window() function to get the contents of the drawing area into a GdkPixbuf.Pixbuf and then use the GdkPixbuf.Pixbuf.savev() function to write the pixbuf as an image on disk.

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', [], [])

While this works, it'd still be nice to see if someone could confirm this is the right way or to see if there is any other alternative.

这篇关于将Gtk.DrawingArea或Cairo模式的内容保存到磁盘上的映像中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆