[gthumb: 12/23] contact_sheet: implemented the squared thumbnail option



commit 2b4daa90242df284bb4593d80d594652d04101b1
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Fri Dec 24 13:20:37 2010 +0100

    contact_sheet: implemented the squared thumbnail option

 .../contact_sheet/gth-contact-sheet-creator.c      |   17 +++-
 extensions/webalbums/gth-web-exporter.c            |  108 +-------------------
 gthumb/pixbuf-utils.c                              |   80 ++++++++++++++-
 gthumb/pixbuf-utils.h                              |    7 ++
 4 files changed, 104 insertions(+), 108 deletions(-)
---
diff --git a/extensions/contact_sheet/gth-contact-sheet-creator.c b/extensions/contact_sheet/gth-contact-sheet-creator.c
index 5d5030b..5249a1b 100644
--- a/extensions/contact_sheet/gth-contact-sheet-creator.c
+++ b/extensions/contact_sheet/gth-contact-sheet-creator.c
@@ -936,6 +936,7 @@ static void
 load_current_image (GthContactSheetCreator *self)
 {
 	ItemData *item_data;
+	int       requested_size;
 
 	if (self->priv->current_file == NULL) {
 		if (self->priv->sort_type->cmp_func != 0)
@@ -953,9 +954,16 @@ load_current_image (GthContactSheetCreator *self)
 			   FALSE,
 			   ((double) ++self->priv->n_loaded_files) / (self->priv->n_files + 1));
 
+	if (self->priv->squared_thumbnails)
+		/* the squared thumbnail requires the original size to avoid
+		 * a thumbnail upscaling that degrades the image quality. */
+		requested_size = -1;
+	else
+		requested_size = MAX (self->priv->thumb_height, self->priv->thumb_width);
+
 	gth_image_loader_load (self->priv->image_loader,
 			       item_data->file_data,
-			       MIN (self->priv->thumb_height, self->priv->thumb_width),
+			       requested_size,
 			       G_PRIORITY_DEFAULT,
 			       gth_task_get_cancellable (GTH_TASK (self)),
 			       image_loader_ready_cb,
@@ -987,10 +995,15 @@ image_loader_ready_cb (GObject      *source_object,
 	}
 
 	item_data = self->priv->current_file->data;
-	item_data->thumbnail = pixbuf;
+	if (self->priv->squared_thumbnails)
+		item_data->thumbnail = _gdk_pixbuf_scale_squared (pixbuf, MIN (self->priv->thumb_height, self->priv->thumb_width), GDK_INTERP_BILINEAR);
+	else
+		item_data->thumbnail = g_object_ref (pixbuf);
 	item_data->original_width = original_width;
 	item_data->original_height = original_height;
 
+	g_object_unref (pixbuf);
+
 	self->priv->current_file = self->priv->current_file->next;
 	load_current_image (self);
 }
diff --git a/extensions/webalbums/gth-web-exporter.c b/extensions/webalbums/gth-web-exporter.c
index 3ef5e3c..ca53b40 100644
--- a/extensions/webalbums/gth-web-exporter.c
+++ b/extensions/webalbums/gth-web-exporter.c
@@ -2479,81 +2479,6 @@ copy_current_file (GthWebExporter *self)
 }
 
 
-static GdkPixbuf *
-pixbuf_scale (const GdkPixbuf *src,
-	      int              dest_width,
-	      int              dest_height,
-	      GdkInterpType    interp_type)
-{
-	GdkPixbuf *dest;
-
-	if (! gdk_pixbuf_get_has_alpha (src))
-		return gdk_pixbuf_scale_simple (src, dest_width, dest_height, interp_type);
-
-	g_return_val_if_fail (src != NULL, NULL);
-	g_return_val_if_fail (dest_width > 0, NULL);
-	g_return_val_if_fail (dest_height > 0, NULL);
-
-	dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha (src), 8, dest_width, dest_height);
-	if (dest == NULL)
-		return NULL;
-
-	gdk_pixbuf_composite_color (src,
-				    dest,
-				    0, 0, dest_width, dest_height, 0, 0,
-				    (double) dest_width / gdk_pixbuf_get_width (src),
-				    (double) dest_height / gdk_pixbuf_get_height (src),
-				    interp_type,
-				    255,
-				    0, 0,
-				    200,
-				    0xFFFFFF,
-				    0xFFFFFF);
-
-	return dest;
-}
-
-
-static GdkPixbuf *
-create_squared_thumbnail (GdkPixbuf     *p,
-			  int            size,
-			  GdkInterpType  interp_type)
-{
-	int        w, h, tw, th;
-	GdkPixbuf *p1;
-	int        x, y;
-	GdkPixbuf *p2;
-
-	w = gdk_pixbuf_get_width (p);
-	h = gdk_pixbuf_get_height (p);
-
-	if ((w < size) && (h < size))
-		return gdk_pixbuf_copy (p);
-
-	if (w > h) {
-		th = size;
-		tw = (int) (((double) w / h) * th);
-	}
-	else {
-		tw = size;
-		th = (int) (((double) h / w) * tw);
-	}
-
-	p1 = pixbuf_scale (p, tw, th, interp_type);
-
-	if ((tw == size) && (th == size))
-		return p1;
-
-	x = (tw - size) / 2;
-	y = (th - size) / 2;
-	p2 = gdk_pixbuf_new_subpixbuf (p1, x, y, size, size);
-
-	g_object_unref (p1);
-
-	return p2;
-}
-
-
 static int
 image_data_cmp (gconstpointer a,
 		gconstpointer b,
@@ -2602,7 +2527,7 @@ image_loader_ready_cb (GObject      *source_object,
 		{
 			GdkPixbuf *scaled;
 
-			scaled = pixbuf_scale (pixbuf, w, h, GDK_INTERP_BILINEAR);
+			scaled = _gdk_pixbuf_scale_composite (pixbuf, w, h, GDK_INTERP_BILINEAR);
 			g_object_unref (idata->image);
 			idata->image = scaled;
 		}
@@ -2626,7 +2551,7 @@ image_loader_ready_cb (GObject      *source_object,
 					     FALSE))
 		{
 			GdkPixbuf *scaled;
-			scaled = pixbuf_scale (pixbuf, w, h, GDK_INTERP_BILINEAR);
+			scaled = _gdk_pixbuf_scale_composite (pixbuf, w, h, GDK_INTERP_BILINEAR);
 			g_object_unref (idata->preview);
 			idata->preview = scaled;
 		}
@@ -2655,7 +2580,7 @@ image_loader_ready_cb (GObject      *source_object,
 		if (self->priv->squared_thumbnails) {
 			GdkPixbuf *squared;
 
-			squared = create_squared_thumbnail (idata->thumb, self->priv->thumb_width, GDK_INTERP_BILINEAR);
+			squared = _gdk_pixbuf_scale_squared (idata->thumb, self->priv->thumb_width, GDK_INTERP_BILINEAR);
 			g_object_unref (idata->thumb);
 			idata->thumb = squared;
 		}
@@ -2666,34 +2591,9 @@ image_loader_ready_cb (GObject      *source_object,
 		{
 			GdkPixbuf *scaled;
 
-			scaled = pixbuf_scale (pixbuf, w, h, GDK_INTERP_BILINEAR);
+			scaled = _gdk_pixbuf_scale_composite (pixbuf, w, h, GDK_INTERP_BILINEAR);
 			g_object_unref (idata->thumb);
 			idata->thumb = scaled;
-
-			if (self->priv->squared_thumbnails) {
-				GdkPixbuf *squared;
-				int        src_x;
-				int        src_y;
-
-				src_x = (self->priv->thumb_width - gdk_pixbuf_get_width (idata->thumb)) / 2;
-				src_y = (self->priv->thumb_height - gdk_pixbuf_get_height (idata->thumb)) / 2;
-
-				g_print ("[%d, %d] => (%d, %d)[%d, %d]",
-						gdk_pixbuf_get_width (idata->thumb),
-						gdk_pixbuf_get_height (idata->thumb),
-						src_x,
-						src_y,
-						self->priv->thumb_width,
-						self->priv->thumb_height);
-
-				squared = gdk_pixbuf_new_subpixbuf (idata->thumb,
-								    src_x,
-								    src_y,
-								    self->priv->thumb_width,
-								    self->priv->thumb_height);
-				g_object_unref (idata->thumb);
-				idata->thumb = squared;
-			}
 		}
 	}
 
diff --git a/gthumb/pixbuf-utils.c b/gthumb/pixbuf-utils.c
index c856115..69c8b73 100644
--- a/gthumb/pixbuf-utils.c
+++ b/gthumb/pixbuf-utils.c
@@ -144,8 +144,6 @@ _gdk_pixbuf_scale_simple_safe (const GdkPixbuf *src,
 	x_ratio = gdk_pixbuf_get_width (src) / dest_width;
 	y_ratio = gdk_pixbuf_get_height (src) / dest_height;
 
-
-
 	if (x_ratio > 100)
 		/* Scale down to 10x the requested size first. */
 		temp_width = 10 * dest_width;
@@ -165,6 +163,84 @@ _gdk_pixbuf_scale_simple_safe (const GdkPixbuf *src,
 }
 
 
+GdkPixbuf *
+_gdk_pixbuf_scale_composite (const GdkPixbuf *src,
+			     int              dest_width,
+			     int              dest_height,
+			     GdkInterpType    interp_type)
+{
+	GdkPixbuf *dest;
+
+	if (! gdk_pixbuf_get_has_alpha (src))
+		return _gdk_pixbuf_scale_simple_safe (src, dest_width, dest_height, interp_type);
+
+	g_return_val_if_fail (src != NULL, NULL);
+	g_return_val_if_fail (dest_width > 0, NULL);
+	g_return_val_if_fail (dest_height > 0, NULL);
+
+	dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha (src), 8, dest_width, dest_height);
+	if (dest == NULL)
+		return NULL;
+
+	gdk_pixbuf_composite_color (src,
+				    dest,
+				    0, 0, dest_width, dest_height, 0, 0,
+				    (double) dest_width / gdk_pixbuf_get_width (src),
+				    (double) dest_height / gdk_pixbuf_get_height (src),
+				    interp_type,
+				    255,
+				    0, 0,
+				    200,
+				    0xFFFFFF,
+				    0xFFFFFF);
+
+	return dest;
+}
+
+
+GdkPixbuf *
+_gdk_pixbuf_scale_squared (GdkPixbuf     *p,
+			   int            size,
+			   GdkInterpType  interp_type)
+{
+	int        w, h, tw, th;
+	GdkPixbuf *p1;
+	int        x, y;
+	GdkPixbuf *p2;
+
+	w = gdk_pixbuf_get_width (p);
+	h = gdk_pixbuf_get_height (p);
+
+	if ((w < size) && (h < size))
+		return gdk_pixbuf_copy (p);
+
+	if (w > h) {
+		th = size;
+		tw = (int) (((double) w / h) * th);
+	}
+	else {
+		tw = size;
+		th = (int) (((double) h / w) * tw);
+	}
+
+	if ((tw > size) || (th > size))
+		p1 = _gdk_pixbuf_scale_composite (p, tw, th, interp_type);
+	else
+		p1 = g_object_ref (p);
+
+	if ((tw == size) && (th == size))
+		return p1;
+
+	x = (tw - size) / 2;
+	y = (th - size) / 2;
+	p2 = gdk_pixbuf_new_subpixbuf (p1, x, y, size, size);
+
+	g_object_unref (p1);
+
+	return p2;
+}
+
+
 /*
  * Returns a transformed image.
  */
diff --git a/gthumb/pixbuf-utils.h b/gthumb/pixbuf-utils.h
index 1752581..5f3b5b2 100644
--- a/gthumb/pixbuf-utils.h
+++ b/gthumb/pixbuf-utils.h
@@ -37,6 +37,13 @@ GdkPixbuf * _gdk_pixbuf_scale_simple_safe      (const GdkPixbuf *src,
 					        int              dest_width,
 					        int              dest_height,
 					        GdkInterpType    interp_type);
+GdkPixbuf * _gdk_pixbuf_scale_composite        (const GdkPixbuf *src,
+			     	     	        int              dest_width,
+			     	     	        int              dest_height,
+			     	     	        GdkInterpType    interp_type);
+GdkPixbuf * _gdk_pixbuf_scale_squared          (GdkPixbuf       *src,
+		  	  	  	  	int              size,
+		  	  	  	  	GdkInterpType    interp_type);
 GdkPixbuf * _gdk_pixbuf_transform              (GdkPixbuf       *src,
 					        GthTransform     transform);
 void        _gdk_pixbuf_colorshift             (GdkPixbuf       *dest,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]