将Gtk.DrawingArea或Cairo模式的内容保存到磁盘上的映像中 [英] Save the contents of a Gtk.DrawingArea or Cairo pattern to an image on disk
问题描述
我有一个小型的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屋!