[dia] [embedded image] implement and use dia_image_save() ...
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] [embedded image] implement and use dia_image_save() ...
- Date: Fri, 11 Mar 2011 21:16:54 +0000 (UTC)
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]