are attached. Ignore the last mails about the file preview patches. I'm not sure what will happen on Windows. I know there are gtk apps storing preferences etc. in ".hidden" folders, even though they are visible in Windows. To supply .ora file thumbnails for Windows, someone would have to do some little c magic as explained here http://msdn.microsoft.com/en-us/library/cc144114(v=VS.85).aspx
Till
>From 823ac9b89e210a07fa1fe623c96340b123b70614 Mon Sep 17 00:00:00 2001 From: Till Hartmann <[email protected]> Date: Sun, 4 Jul 2010 14:57:52 +0200 Subject: [PATCH 1/2] Improve file preview handling --- gui/filehandling.py | 11 +++++++++-- lib/helpers.py | 30 ++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/gui/filehandling.py b/gui/filehandling.py index 871f071..14b5da8 100644 --- a/gui/filehandling.py +++ b/gui/filehandling.py @@ -269,11 +269,18 @@ class FileHandler(object): loader.write(data) loader.close() pixbuf = loader.get_pixbuf() + pixbuf = helpers.scale_proportionally(pixbuf, 128, 128) return pixbuf else: try: - #TODO do not scale images smaller than 256x256 up. - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, 256, 256) + #TODO find out how to use windows' "Thumbs.db" (sqlite?) + thumb_filename = helpers.get_freedesktop_thumbnail_file(filename) + if thumb_filename: + pixbuf = gtk.gdk.pixbuf_new_from_file(thumb_filename) + pixbuf = helpers.pixbuf_thumbnail(pixbuf, 128, 128, True) # width should always be 128px + else: + pixbuf = gtk.gdk.pixbuf_new_from_file(filename) + pixbuf = helpers.pixbuf_thumbnail(pixbuf, 128, 128, True) return pixbuf except: pass diff --git a/lib/helpers.py b/lib/helpers.py index f6ca5af..5e58358 100644 --- a/lib/helpers.py +++ b/lib/helpers.py @@ -12,6 +12,9 @@ import colorsys, urllib, gc from gtk import gdk # for gdk_pixbuf stuff import mypaintlib +import hashlib +import os + try: from json import dumps as json_dumps, loads as json_loads print "builtin python 2.6 json support" @@ -111,7 +114,24 @@ def gdkpixbuf2numpy(pixbuf): arr = pixbuf.get_pixels_array() return mypaintlib.gdkpixbuf_numeric2numpy(arr) -def pixbuf_thumbnail(src, w, h): +def get_freedesktop_thumbnail_file(filename): + file_hash = hashlib.md5('file://'+filename).hexdigest() + tb_filename = os.path.join(os.path.expanduser('~/.thumbnails/normal'), file_hash) + '.png' + if os.path.exists(tb_filename): + return tb_filename + else: + return None + +def scale_proportionally(pixbuf, w, h): + width = pixbuf.get_width() + height = pixbuf.get_height() + scale = min(w / float(width), h / float(height)) + new_width = int((width * scale)) + new_height = int((height * scale)) + pixbuf = pixbuf.scale_simple(new_width, new_height, gdk.INTERP_BILINEAR) + return pixbuf + +def pixbuf_thumbnail(src, w, h, alpha=False): """ Creates a centered thumbnail of a gdk.pixbuf. """ @@ -128,9 +148,11 @@ def pixbuf_thumbnail(src, w, h): assert w2 <= w and h2 <= h src2 = src.scale_simple(w2, h2, gdk.INTERP_BILINEAR) - dst = gdk.Pixbuf(gdk.COLORSPACE_RGB, False, 8, w, h) - dst.fill(0xffffffff) # white background - + dst = gdk.Pixbuf(gdk.COLORSPACE_RGB, alpha, 8, w, h) + if alpha: + dst.fill(0xffffff00) # transparent background + else: + dst.fill(0xffffffff) # white background src2.copy_area(0, 0, w2, h2, dst, (w-w2)/2, (h-h2)/2) return dst -- 1.7.0.4
>From 3fd0202477f5923d65f204c56ba760d010992bba Mon Sep 17 00:00:00 2001 From: Till Hartmann <[email protected]> Date: Sun, 4 Jul 2010 15:11:33 +0200 Subject: [PATCH 2/2] Store thumbnails according to FDO spec. See http://jens.triq.net/thumbnail-spec/introduction.html (Needs testing on Windows) --- gui/filehandling.py | 55 ++++++++++++++++++++++++++------------------------ lib/document.py | 7 +----- lib/helpers.py | 31 ++++++++++++---------------- 3 files changed, 43 insertions(+), 50 deletions(-) diff --git a/gui/filehandling.py b/gui/filehandling.py index 14b5da8..4e5b8a5 100644 --- a/gui/filehandling.py +++ b/gui/filehandling.py @@ -254,36 +254,39 @@ class FileHandler(object): def update_preview_cb(self, file_chooser, preview): filename = file_chooser.get_preview_filename() pixbuf = self.get_preview_image(filename) - preview.set_from_pixbuf(pixbuf) - file_chooser.set_preview_widget_active(pixbuf != None) + if pixbuf: + if os.path.splitext(filename)[1].lower() == ".ora": #only store .ora thumbnails + helpers.save_freedesktop_thumbnail(pixbuf, filename) + pixbuf = helpers.pixbuf_thumbnail(pixbuf, 128, 128, True) + preview.set_from_pixbuf(pixbuf) + file_chooser.set_preview_widget_active(True) + else: + pass def get_preview_image(self, filename): if filename: - if os.path.splitext(filename)[1].lower() == ".ora": - ora = zipfile.ZipFile(file(filename)) - try: - data = ora.read("Thumbnails/thumbnail.png") - except KeyError: - return None - loader = gtk.gdk.PixbufLoader("png") - loader.write(data) - loader.close() - pixbuf = loader.get_pixbuf() - pixbuf = helpers.scale_proportionally(pixbuf, 128, 128) + try: + #TODO find out how to use windows' "Thumbs.db" (sqlite?) + thumb_filename = helpers.get_freedesktop_thumbnail_file(filename) + if thumb_filename: + pixbuf = gtk.gdk.pixbuf_new_from_file(thumb_filename) + else: + if os.path.splitext(filename)[1].lower() == ".ora": + ora = zipfile.ZipFile(file(filename)) + try: + data = ora.read("Thumbnails/thumbnail.png") + except KeyError: + return None + loader = gtk.gdk.PixbufLoader("png") + loader.write(data) + loader.close() + pixbuf = loader.get_pixbuf() + return pixbuf + + pixbuf = gtk.gdk.pixbuf_new_from_file(filename) return pixbuf - else: - try: - #TODO find out how to use windows' "Thumbs.db" (sqlite?) - thumb_filename = helpers.get_freedesktop_thumbnail_file(filename) - if thumb_filename: - pixbuf = gtk.gdk.pixbuf_new_from_file(thumb_filename) - pixbuf = helpers.pixbuf_thumbnail(pixbuf, 128, 128, True) # width should always be 128px - else: - pixbuf = gtk.gdk.pixbuf_new_from_file(filename) - pixbuf = helpers.pixbuf_thumbnail(pixbuf, 128, 128, True) - return pixbuf - except: - pass + except: + pass def open_cb(self, action): if not self.confirm_destructive_action(): diff --git a/lib/document.py b/lib/document.py index cdf41ad..8b91e2c 100644 --- a/lib/document.py +++ b/lib/document.py @@ -406,13 +406,8 @@ class Document(): t2 = time.time() print ' starting to render image for thumbnail...' pixbuf = self.render_as_pixbuf() - w, h = pixbuf.get_width(), pixbuf.get_height() - if w > h: - w, h = 256, max(h*256/w, 1) - else: - w, h = max(w*256/h, 1), 256 t1 = time.time() - pixbuf = pixbuf.scale_simple(w, h, gdk.INTERP_BILINEAR) + pixbuf = helpers.scale_proportionally(pixbuf, 256, 256) print ' %.3fs scaling thumbnail' % (time.time() - t1) store_pixbuf(pixbuf, 'Thumbnails/thumbnail.png') print ' total %.3fs spent on thumbnail' % (time.time() - t2) diff --git a/lib/helpers.py b/lib/helpers.py index 5e58358..4e4cd54 100644 --- a/lib/helpers.py +++ b/lib/helpers.py @@ -122,12 +122,18 @@ def get_freedesktop_thumbnail_file(filename): else: return None -def scale_proportionally(pixbuf, w, h): - width = pixbuf.get_width() - height = pixbuf.get_height() +def save_freedesktop_thumbnail(pixbuf, filename): + file_hash = hashlib.md5('file://'+filename).hexdigest() + tb_filename = os.path.join(os.path.expanduser('~/.thumbnails/normal'), file_hash) + '.png' + pixbuf = scale_proportionally(pixbuf, 128,128) + pixbuf.save(tb_filename, 'png') + +def scale_proportionally(pixbuf, w, h, shrink_only=True): + width, height = pixbuf.get_width(), pixbuf.get_height() scale = min(w / float(width), h / float(height)) - new_width = int((width * scale)) - new_height = int((height * scale)) + if shrink_only and scale >= 1: + return pixbuf + new_width, new_height = int(width * scale), int(height * scale) pixbuf = pixbuf.scale_simple(new_width, new_height, gdk.INTERP_BILINEAR) return pixbuf @@ -135,19 +141,8 @@ def pixbuf_thumbnail(src, w, h, alpha=False): """ Creates a centered thumbnail of a gdk.pixbuf. """ - src_w = src.get_width() - src_h = src.get_height() - - w2, h2 = src_w, src_h - if w2 > w: - h2 = h2*w/w2 - w2 = w - if h2 > h: - w2 = w2*h/h2 - h2 = h - assert w2 <= w and h2 <= h - src2 = src.scale_simple(w2, h2, gdk.INTERP_BILINEAR) - + src2 = scale_proportionally(src, w, h) + w2, h2 = src2.get_width(), src2.get_height() dst = gdk.Pixbuf(gdk.COLORSPACE_RGB, alpha, 8, w, h) if alpha: dst.fill(0xffffff00) # transparent background -- 1.7.0.4
_______________________________________________ Mypaint-discuss mailing list [email protected] https://mail.gna.org/listinfo/mypaint-discuss
