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

Reply via email to