[evolution-patches] Plugin for resizing inline attachments (images)
- From: Srinivasa Ragavan <sragavan novell com>
- To: evolution-patches lists ximian com
- Cc: notzed novell com
- Subject: [evolution-patches] Plugin for resizing inline attachments (images)
- Date: Tue, 14 Jun 2005 11:39:03 +0530
Hi,
I have written a e-plugin to resize inline display of images to
available width.
It basically converts the part to a pixbuf, resizes it and decodes to a
jpeg (a pixbuf when tried saving to a buffer, has to be decoded to some
format) and is converted to a part and passed to the default handler.
This is the approach, i have followed. It still saves the original
file.
There is a alternate approach as well.
Every image is written with a <img src="xxxx" > tag. Get the image size
from the part, and if it is more than the available width, then add a
width="xxx" so that gtkhtml automatically resizes it for bigger images.
Thanks
Srini.
--- /dev/null 2005-03-20 01:06:14.000000000 +0530
+++ image-resize-plugin.c 2005-06-14 10:16:28.000000000 +0530
@@ -0,0 +1,170 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Author: Srinivasa Ragavan <sragavan novell com>
+ *
+ * Copyright 2004 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+
+#ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H
+#include <libgnomeui/libgnomeui.h>
+#endif
+
+#include <camel/camel-mime-part.h>
+#include <camel/camel-stream-mem.h>
+
+#include <mail/em-format.h>
+#include <mail/em-format-html.h>
+#include <mail/em-format-hook.h>
+#include <e-util/e-mktemp.h>
+
+void org_gnome_evolution_format_image_resize(void *ep, EMFormatHookTarget *t);
+
+static gboolean
+save_to_buffer (char *buffer, int len, GError **err, CamelStream *stream)
+{
+ return camel_stream_write (stream, buffer, len) != -1;
+
+}
+void
+org_gnome_evolution_format_image_resize(void *ep, EMFormatHookTarget *t)
+{
+ CamelStream *out = NULL, *stream = NULL;
+ CamelMimePart *mainpart;
+ CamelDataWrapper *content, *dw;
+ GtkWidget *image = NULL;
+ GdkPixbuf *pixbuf=NULL;
+ GdkPixbufLoader *loader;
+ int orig_width, orig_height, avail_width, avail_height;
+ float ratio = 1.0;
+ char buffer [1024];
+ int len = 0;
+
+ out = camel_stream_mem_new ();
+ if (out == NULL)
+ goto fail;
+
+ content = camel_medium_get_content_object((CamelMedium *)t->part);
+ if (content == NULL)
+ goto fail;
+ if (camel_data_wrapper_decode_to_stream(content, out) == -1
+ || camel_stream_flush(out) == -1) {
+ goto fail;
+ }
+ camel_stream_reset (out);
+
+ loader = gdk_pixbuf_loader_new();
+ do {
+ len = camel_stream_read(out, buffer, sizeof (buffer));
+ if (len > 0)
+ gdk_pixbuf_loader_write(loader, buffer, len, NULL);
+ } while (len>0);
+
+ camel_object_unref(out);
+ out = NULL;
+
+ gdk_pixbuf_loader_close(loader, NULL);
+ pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
+
+ avail_height = ((GtkWidget *)((EMFormatHTML *) t->format)->html)->allocation.height;
+ avail_width = ((GtkWidget *)((EMFormatHTML *) t->format)->html)->allocation.width;
+
+ orig_height = gdk_pixbuf_get_height (pixbuf);
+ orig_width = gdk_pixbuf_get_width (pixbuf);
+
+ /* Lets make it to the 95% of the space*/
+ avail_width = avail_width *95 / 100;
+
+ if (orig_width > avail_width)
+ ratio = (float)orig_width / (float)avail_width;
+ else
+ goto fail; /* We just pass to the default handler. We dont have to shrink further */
+
+ orig_width = (int) (orig_width / ratio);
+ orig_height = (int) (orig_height / ratio);
+
+#ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H
+ pixbuf = gnome_thumbnail_scale_down_pixbuf (pixbuf, orig_width, orig_height);
+#else
+ pixbuf = gdk_pixbuf_scale_simple(pixbuf, orig_width, orig_height, GDK_INTERP_BILINEAR);
+#endif
+
+ stream = camel_stream_mem_new ();
+
+ if (!gdk_pixbuf_save_to_callback (pixbuf, (GdkPixbufSaveFunc)save_to_buffer, stream, "jpeg", NULL, NULL)) {
+ g_warning ("Image-resize-plugin: Unable to resize\n");
+ goto fail;
+ }
+
+ mainpart = camel_mime_part_new();
+
+ dw = camel_data_wrapper_new();
+ camel_data_wrapper_construct_from_stream(dw, stream);
+ camel_object_unref(stream);
+
+ camel_mime_part_set_encoding(mainpart, CAMEL_TRANSFER_ENCODING_BINARY);
+
+ camel_medium_set_content_object((CamelMedium *)mainpart, dw);
+ camel_object_unref(dw);
+
+
+ camel_data_wrapper_set_mime_type((CamelDataWrapper *)mainpart, camel_data_wrapper_get_mime_type (content));
+
+ camel_mime_part_set_filename(mainpart, camel_mime_part_get_filename (t->part));
+
+ t->item->handler.old->handler(t->format, t->stream, mainpart, t->item->handler.old);
+
+ camel_object_unref (mainpart);
+
+ goto ok;
+fail:
+ if (out)
+ camel_object_unref (out);
+ if (stream)
+ camel_object_unref (stream);
+
+ t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);
+ok:
+
+ if (pixbuf)
+ gdk_pixbuf_unref (pixbuf);
+
+ if (image)
+ gtk_widget_destroy (image);
+ return;
+}
+
+int e_plugin_lib_enable(EPluginLib *ep, int enable);
+
+int
+e_plugin_lib_enable(EPluginLib *ep, int enable)
+{
+ int ok = 0;
+
+ if (enable) {
+ printf("Enabling the image resize plug-in\n");
+ }
+
+ return ok;
+}
--- /dev/null 2005-03-20 01:06:14.000000000 +0530
+++ Makefile.am 2005-06-13 13:57:01.000000000 +0530
@@ -0,0 +1,16 @@
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/camel \
+ $(EVOLUTION_MAIL_CFLAGS)
+
+ EVO_PLUGIN_RULE@
+
+plugin_DATA = org-gnome-evolution-image-resize-plugin.eplug
+plugin_LTLIBRARIES = liborg-gnome-evolution-image-resize-plugin.la
+
+liborg_gnome_evolution_image_resize_plugin_la_SOURCES = image-resize-plugin.c
+liborg_gnome_evolution_image_resize_plugin_la_LDFLAGS = -module -avoid-version
+liborg_gnome_evolution_image_resize_plugin_la_LIBADD = \
+ $(EVOLUTION_MAIL_LIBS)
+
+EXTRA_DIST = org-gnome-evolution-image-resize-plugin.eplug.in
--- /dev/null 2005-03-20 01:06:14.000000000 +0530
+++ org-gnome-evolution-image-resize-plugin.eplug.in 2005-06-14 10:14:01.000000000 +0530
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<e-plugin-list>
+ <e-plugin
+ type="shlib"
+ id="org.gnome.evolution.plugin.image-resize-plugin"
+ location="@PLUGINDIR@/liborg-gnome-evolution-image-resize-plugin.so"
+ load-on-startup="true"
+ domain="+GETTEXT_PACKAGE+"
+ localedir="+LOCALEDIR+"
+ name="Image resize">
+ <description>A simple plugin which scales down image attachments to fit to available width.</description>
+ <author name="Srinivasa Ragavan" email="sragavan novell com"/>
+
+ <hook class="org.gnome.evolution.mail.format:1.0">
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/gif"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/jpeg"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/png"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-png"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/tiff"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-bmp"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/bmp"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/svg"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-cmu-raster"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-ico"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-portable-anymap"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-portable-bitmap"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-portable-graymap"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-portable-pixmap"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/x-xpixmap"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/jpg"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+
+ <group id="EMFormatHTMLDisplay">
+ <item flags="inline_disposition" mime_type="image/pjpeg"
+ format="org_gnome_evolution_format_image_resize"/>
+ </group>
+ </hook>
+ </e-plugin>
+</e-plugin-list>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]