[dia] [embedded image] implement and use dia_image_save() ...



commit fa72f59efc129777c4085a60d9a5bd55a7b2889f
Author: Hans Breuer <hans breuer org>
Date:   Fri Mar 11 22:16:24 2011 +0100

    [embedded image] implement and use dia_image_save() ...
    
    ... to export embedded images when the inline_data switch is flipped
    and a filename is set. Add an export script, which does it for all
    inlined images.

 lib/dia_image.c                  |   68 ++++++++++++++++++++++++++++++++++++-
 lib/dia_image.h                  |    1 +
 lib/libdia.def                   |    1 +
 objects/standard/image.c         |   21 +++++++----
 plug-ins/python/uninline_data.py |   48 ++++++++++++++++++++++++++
 5 files changed, 129 insertions(+), 10 deletions(-)
---
diff --git a/lib/dia_image.c b/lib/dia_image.c
index 101b5f4..13409eb 100644
--- a/lib/dia_image.c
+++ b/lib/dia_image.c
@@ -19,6 +19,7 @@
 #include <config.h>
 #include <string.h> /* memmove */
 
+#include "intl.h"
 #include "geometry.h"
 #include "dia_image.h"
 #include "message.h"
@@ -227,8 +228,8 @@ dia_image_draw(DiaImage *image, GdkWindow *window, GdkGC *gc,
 
   if (width < 1 || height < 1)
     return;
-  if (gdk_pixbuf_get_width(image->image) != width ||
-      gdk_pixbuf_get_height(image->image) != height) {
+  if (gdk_pixbuf_get_width(image->image) > width ||
+      gdk_pixbuf_get_height(image->image) > height) {
     /* Using TILES to make it look more like PostScript */
 #ifdef SCALING_CACHE
     if (image->scaled == NULL ||
@@ -259,6 +260,69 @@ dia_image_draw(DiaImage *image, GdkWindow *window, GdkGC *gc,
 #endif
 }
 
+static gchar *
+_guess_format (const gchar *filename)
+{
+  const char* test = strrchr (filename, '.');
+  GSList* formats = gdk_pixbuf_get_formats ();
+  GSList* sl;
+  gchar *type = NULL;
+
+  if (test)
+    ++test;
+  else
+    test = "png";
+
+  for (sl = formats; sl != NULL; sl = g_slist_next (sl)) {
+    GdkPixbufFormat* format = (GdkPixbufFormat*)sl->data;
+
+    if (gdk_pixbuf_format_is_writable (format)) {
+      gchar* name = gdk_pixbuf_format_get_name (format);
+      gchar **extensions = gdk_pixbuf_format_get_extensions (format);
+      int i;
+
+      for (i = 0; extensions[i] != NULL; ++i) {
+        const gchar *ext = extensions[i];
+        if (strcmp (test, ext) == 0) {
+	  type = g_strdup (name);
+	  break;
+	}
+      }
+      g_strfreev (extensions);
+    }
+    g_slist_free (formats);
+    if (type)
+      break;
+  }
+  return type;
+}
+
+gboolean
+dia_image_save(DiaImage *image, const gchar *filename)
+{
+  gboolean saved = FALSE;
+
+  if (image->image) {
+    GError *error = NULL;
+    gchar *type = _guess_format (filename);
+    
+    if (type)
+      saved = gdk_pixbuf_save (image->image, filename, type, &error, NULL);
+    if (saved) {
+      g_free (image->filename);
+      image->filename = g_strdup (filename);
+    } else {
+      message_warning(_("Could not save file:\n%s\n%s"),
+		      dia_message_filename(filename),
+                      error->message);
+      g_error_free (error);
+    }
+
+    g_free (type);
+  }
+  return saved;
+}
+
 /** Get the width of an image.
  * @param image An image object
  * @returns The natural width of the object in pixels.
diff --git a/lib/dia_image.h b/lib/dia_image.h
index 4b2d598..95c0a5e 100644
--- a/lib/dia_image.h
+++ b/lib/dia_image.h
@@ -35,6 +35,7 @@ void dia_image_add_ref(DiaImage *image);
 void dia_image_unref(DiaImage *image);
 void dia_image_draw(DiaImage *image, GdkWindow *window, GdkGC *gc,
 		    int x, int y, int width, int height);
+gboolean dia_image_save(DiaImage *image, const gchar *filename);
 
 int dia_image_width(const DiaImage *image);
 int dia_image_rowstride(const DiaImage *image);
diff --git a/lib/libdia.def b/lib/libdia.def
index 513a397..c9d058e 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -267,6 +267,7 @@ EXPORTS
  dia_image_get_broken
  dia_image_height
  dia_image_load
+ dia_image_save
  dia_image_mask_data
  dia_image_unref
  dia_image_rgb_data
diff --git a/objects/standard/image.c b/objects/standard/image.c
index 0be5b76..1591880 100644
--- a/objects/standard/image.c
+++ b/objects/standard/image.c
@@ -182,7 +182,7 @@ static void
 image_get_props(Image *image, GPtrArray *props)
 {
   if (image->inline_data)
-    image->pixbuf = dia_image_pixbuf (image->image);
+    image->pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image);
   object_get_props_from_offsets(&image->element.object, image_offsets, props);
 }
 
@@ -192,7 +192,8 @@ image_set_props(Image *image, GPtrArray *props)
   struct stat st;
   time_t mtime = 0;
   char *old_file = image->file ? g_strdup(image->file) : "";
-  GdkPixbuf *old_pixbuf = dia_image_pixbuf (image->image);
+  const GdkPixbuf *old_pixbuf = dia_image_pixbuf (image->image);
+  gboolean was_inline = image->inline_data;
 
   object_set_props_from_offsets(&image->element.object, image_offsets, props);
 
@@ -206,7 +207,7 @@ image_set_props(Image *image, GPtrArray *props)
       if (image->image)
         g_object_unref (image->image);
       image->image = dia_image_new_from_pixbuf (image->pixbuf ? image->pixbuf : pixbuf);
-      image->pixbuf = dia_image_pixbuf (image->image);
+      image->pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image);
       if (pixbuf)
 	g_object_unref (pixbuf);
     } else {
@@ -222,14 +223,18 @@ image_set_props(Image *image, GPtrArray *props)
     mtime = st.st_mtime;
 
   /* handle changing the image. */
-  if (image->file && (strcmp(image->file, old_file) != 0 || image->mtime != mtime)) {
+  if (image->file && image->pixbuf && was_inline && !image->inline_data) {
+    /* export inline data */
+    if (was_inline && !image->inline_data)
+      /* if saving fails we keep it inline */
+      image->inline_data = !dia_image_save (image->image, image->file);
+  } else if (image->file && (strcmp(image->file, old_file) != 0 || image->mtime != mtime)) {
     Element *elem = &image->element;
     DiaImage *img = NULL;
 
-    img = dia_image_load(image->file);
-    if (img)
+    if ((img = dia_image_load(image->file)) != NULL)
       image->image = img;
-    else
+    else if (!image->pixbuf) /* dont overwrite inlined */
       image->image = dia_image_get_broken();
     elem->height = (elem->width*(float)dia_image_height(image->image))/
       (float)dia_image_width(image->image);
@@ -661,7 +666,7 @@ image_save(Image *image, ObjectNode obj_node, const char *filename)
     data_add_boolean (new_attribute(obj_node, "inline_data"), image->inline_data);
 
     /* just to be sure to get the currently visible */
-    pixbuf = dia_image_pixbuf (image->image);
+    pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image);
     if (pixbuf != image->pixbuf && image->pixbuf != NULL)
       message_warning (_("Inconsistent pixbuf during image save."));
     if (pixbuf)
diff --git a/plug-ins/python/uninline_data.py b/plug-ins/python/uninline_data.py
new file mode 100644
index 0000000..0cc8066
--- /dev/null
+++ b/plug-ins/python/uninline_data.py
@@ -0,0 +1,48 @@
+#   Un-inline (i.e. save) embedded images
+#
+#   Copyright (c) 2011, Hans Breuer <hans breuer org>
+#
+#    This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import os, string, sys, dia
+
+class UninlineRenderer :
+	def __init__ (self) :
+		self.count = 0
+	def begin_render (self, data, filename) :
+		imgmap = {}
+		dirname = os.path.dirname (filename)
+		ext = filename[string.rfind(filename, ".")+1:]
+		for layer in data.layers :
+			for o in layer.objects :
+				if "inline_data" in o.properties.keys() :
+					if o.properties["inline_data"].value :
+						# remember by position
+						pos = o.properties["obj_pos"].value
+						xk = "%03g" % pos.x
+						yk = "%03g" % pos.y
+						key = "L" + layer.name + "x" + xk + "y" + yk
+						imgmap[key] = o
+			for k, o in imgmap.iteritems() :
+				fname = dirname + "/" + k + "." + ext
+				print fname
+				o.properties["image_file"] = fname
+				o.properties["inline_data"] = 0
+
+	def end_render (self) :
+		pass
+		
+# dia-python keeps a reference to the renderer class and uses it on demand
+dia.register_export ("Uninline Images", "png", UninlineRenderer())



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