如何设置GtkImage的大小

时间:2014-06-26 17:17:35

标签: python gtk3 pygobject

我从网页下载图片时,图片太大(通常最大边距为600px),我想将其缩小以适应220x220px的盒子。

我有它的代码 - 除了最终大小。下载图像,然后放入GtkImage(它来自Glade布局)。我将其下载到临时文件中,因为我似乎无法直接将数据从网站传输到图像中。现在问题是这个图像在应用程序中显示时太大了。

f = tempfile.NamedTemporaryFile()
try:
    res = urllib2.urlopen('http://hikingtours.hk/images/meetingpoint_%s.jpg'% (self.tours[tourid]['id'], ))
    f.write(res.read())

    # This f.read() call is necassary, without it, the image
    # can not be set properly.
    f.read()
    self.edit_tour_meetingpoint_image.set_from_file(f.name)
    self.edit_tour_meetingpoint_image.show()

except:
    raise

f.close()

另一方面,我喜欢摆脱那个临时文件构建:)

请注意,我使用的是GTK3。

2 个答案:

答案 0 :(得分:4)

使用Gdk.Pixbuf.new_from_file_at_scale()和Gtk.Image.set_from_pixbuf():

pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(f.name, width=220, height=220,
                                                 preserve_aspect_ratio=False)
self.edit_tour_meetingpoint_image.set_from_pixbuf(pixbuf)

如果要保留方面,只需将该参数设置为True或使用:GdkPixbuf.Pixbuf.new_from_file_at_size(f.name,width = 220,height = 220)

附注:在使用文件之前需要调用read()的原因是因为它是缓冲的并且尚未写入磁盘。读取调用导致缓冲区刷新,更清晰的技术(从可读性的角度来看)将调用flush()而不是read()。

如果你想摆脱临时文件,请使用Gio模块和流pixbuf:

from gi.repository import Gtk, GdkPixbuf, Gio

file = Gio.File.new_for_uri('http://www.gnome.org/wp-content/themes/gnome-grass/images/gnome-logo.png')
pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale(file.read(cancellable=None),
                                                   width=220, height=220,
                                                   preserve_aspect_ratio=False,
                                                   cancellable=None)
self.edit_tour_meetingpoint_image.set_from_pixbuf(pixbuf)

您可以使用异步图像流进一步处理,然后在pixbuf准备就绪时将完成的结果注入应用程序,在文件传输过程中保持UI中的交互性:

from gi.repository import Gtk, GdkPixbuf, Gio

# standin image until our remote image is loaded, this can also be set in Glade
image = Gtk.Image.new_from_icon_name('image-missing', Gtk.IconSize.DIALOG)

def on_image_loaded(source, async_res, user_data):
    pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(async_res)
    image.set_from_pixbuf(pixbuf)

file = Gio.File.new_for_uri('http://www.gnome.org/wp-content/themes/gnome-grass/images/gnome-logo.png')
GdkPixbuf.Pixbuf.new_from_stream_at_scale_async(file.read(cancellable=None),
                                                220, 220, # width and height
                                                False,    # preserve_aspect_ratio
                                                None,     # cancellable
                                                on_image_loaded, # callback,
                                                None)     # user_data

请注意,由于user_data arg,我们无法在异步版本中使用nice关键字参数。这在pygobject 3.12中消失了,如果不使用user_data实际上可以保留(或者也用作关键字arg)。

答案 1 :(得分:0)

使用pixbuf(gtk的一部分)

def scale(dest, dest_x, dest_y, dest_width, dest_height, offset_x, offset_y, scale_x, scale_y, interp_type)

或简单比例

gtk.gdk.Pixbuf.scale_simple

def scale_simple(dest_width, dest_height, interp_type)

您仍然可以通过导入gdk在gtk3中使用Pixbuf但是您需要导入cairo

import cairo
import Image
import array
from gi.repository import Gtk, GdkPixbuf

width = 25
height = 25
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size('logo.png', width, height)
pil_image = Image.fromstring('RGBA', (width, height), pixbuf.get_pixels())
byte_array = array.array('B', pil_image.tostring())
cairo_surface = cairo.ImageSurface.create_for_data(byte_array, cairo.FORMAT_ARGB32, width, height, width * 4)

Code Sample Reference