Feeding the RGB data directly into the pixbuf sometimes causes image distortions or segfaults, this fixes it

This commit is contained in:
tmolitor 2016-04-10 19:02:07 +02:00
parent 3163157219
commit 8aabfe29c7
1 changed files with 23 additions and 24 deletions

View File

@ -418,48 +418,47 @@ def get_abspath_for_script(scriptname, want_type = False):
else: else:
return path_to_script return path_to_script
# feeding the image directly into the pixbuf seems possible, but is error prone and causes image distortions and segfaults.
# see http://stackoverflow.com/a/8892894/3528174 # see http://stackoverflow.com/a/8892894/3528174
# and https://developer.gnome.org/gdk-pixbuf/unstable/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new-from-bytes # and https://developer.gnome.org/gdk-pixbuf/unstable/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new-from-bytes
def pillow2pixbuf(im): # to learn how this could be done (or look into the mercurial history)
arr = array.array('B', im.tobytes())
width, height = im.size
return GdkPixbuf.Pixbuf.new_from_data(arr, GdkPixbuf.Colorspace.RGB,
False, 8, width, height, width * 3)
def get_pixbuf_from_data(file_data, want_type = False): def get_pixbuf_from_data(file_data, want_type = False):
""" """
Get image data and returns GdkPixbuf.Pixbuf if want_type is True it also Get image data and returns GdkPixbuf.Pixbuf if want_type is True it also
returns 'jpeg', 'png' etc returns 'jpeg', 'png' etc
""" """
# try to open and convert every image format supported by PILLOW to png format pixbufloader = GdkPixbuf.PixbufLoader()
try: try:
im = Image.open(BytesIO(file_data)).convert("RGB") pixbufloader.write(file_data)
pixbuf = pillow2pixbuf(im) pixbufloader.close()
if want_type: pixbuf = pixbufloader.get_pixbuf()
typ = "png" except GLib.GError: # 'unknown image format'
return pixbuf, typ pixbufloader.close()
else:
return pixbuf # try to open and convert this image to png using pillow (if available)
except: log.debug("loading avatar using pixbufloader directly failed, trying to convert avatar image using pillow (if available)")
log.info("Could not use pillow to convert avatar image to pixbuf, trying pixbufloader instead...")
pixbufloader = GdkPixbuf.PixbufLoader() pixbufloader = GdkPixbuf.PixbufLoader()
try: try:
avatar = Image.open(BytesIO(file_data))
output = BytesIO()
avatar.save(output, format='PNG')
file_data = output.getvalue()
output.close()
pixbufloader.write(file_data) pixbufloader.write(file_data)
pixbufloader.close() pixbufloader.close()
pixbuf = pixbufloader.get_pixbuf() pixbuf = pixbufloader.get_pixbuf()
except GLib.GError: # 'unknown image format' except:
pixbufloader.close() log.info("Could not use pillow to convert avatar image, image cannot be displayed")
pixbuf = None
if want_type: if want_type:
return None, None return None, None
else: else:
return None return None
if want_type: if want_type:
typ = pixbufloader.get_format().get_name() typ = pixbufloader.get_format().get_name()
return pixbuf, typ return pixbuf, typ
else: else:
return pixbuf return pixbuf
def get_invisible_cursor(): def get_invisible_cursor():
import cairo import cairo