diff options
| author | Ted Gould <ted@gould.cx> | 2007-08-10 17:38:51 +0000 |
|---|---|---|
| committer | gouldtj <gouldtj@users.sourceforge.net> | 2007-08-10 17:38:51 +0000 |
| commit | b29eafffd0b92cc7b67e5cd877aad5e98b0f0231 (patch) | |
| tree | 167c348e5e11ebf3d8afec37593f023180675039 /src/extension/internal/bitmap/imagemagick.cpp | |
| parent | fix 1767940 (diff) | |
| download | inkscape-b29eafffd0b92cc7b67e5cd877aad5e98b0f0231.tar.gz inkscape-b29eafffd0b92cc7b67e5cd877aad5e98b0f0231.zip | |
r16217@tres: ted | 2007-08-10 10:36:27 -0700
ImageMagick effects patch from Chris Brown. Google Summer of Code
project.
(bzr r3450)
Diffstat (limited to 'src/extension/internal/bitmap/imagemagick.cpp')
| -rw-r--r-- | src/extension/internal/bitmap/imagemagick.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp new file mode 100644 index 000000000..83650aaa7 --- /dev/null +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -0,0 +1,175 @@ +/* + * Authors: + * Christopher Brown <audiere@gmail.com> + * Ted Gould <ted@gould.cx> + * + * Copyright (C) 2007 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <gtkmm/box.h> +#include <gtkmm/adjustment.h> +#include <gtkmm/spinbutton.h> + +#include <glib/gstdio.h> + +#include "desktop.h" +#include "desktop-handles.h" +#include "selection.h" +#include "sp-object.h" +#include "util/glib-list-iterators.h" + +#include "extension/effect.h" +#include "extension/system.h" + +#include "imagemagick.h" + +namespace Inkscape { +namespace Extension { +namespace Internal { +namespace Bitmap { + +bool +ImageMagick::load(Inkscape::Extension::Extension *module) +{ + _loaded = FALSE; + return TRUE; +} + +void +ImageMagick::commitDocument(void) { + _loaded = FALSE; +} + +void +ImageMagick::cancelDocument(void) { + for (int i = 0; i < _imageCount; i++) { + _nodes[i]->setAttribute("xlink:href", _originals[i], true); + } + + _loaded = FALSE; +} + +void +ImageMagick::readImage(const char *xlink, Magick::Image *image) +{ + // Find if the xlink:href is base64 data, i.e. if the image is embedded + char *search = strndup(xlink, 30); + if (strstr(search, "base64") != (char*)NULL) { + // 7 = strlen("base64") + strlen(",") + char* pureBase64 = strstr(xlink, "base64") + 7; + Magick::Blob blob; + blob.base64(pureBase64); + image->read(blob); + } + else { + image->read(xlink); + } +} + +void +ImageMagick::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document) +{ + refreshParameters(module); + + if (!_loaded) + { + SPDesktop *desktop = (SPDesktop*)document; + const GSList *selectedReprList = desktop->selection->reprList(); + int selectCount = g_slist_length((GSList *)selectedReprList); + + // Init the data-holders + _nodes = new Inkscape::XML::Node*[selectCount]; + _originals = new const char*[selectCount]; + _images = new Magick::Image[selectCount]; + _imageCount = 0; + + // Loop through selected nodes + for (; selectedReprList != NULL; selectedReprList = g_slist_next(selectedReprList)) + { + Inkscape::XML::Node *node = reinterpret_cast<Inkscape::XML::Node *>(selectedReprList->data); + if (!strcmp(node->name(), "image") || !strcmp(node->name(), "svg:image")) + { + _nodes[_imageCount] = node; + char const *xlink = node->attribute("xlink:href"); + + _originals[_imageCount] = xlink; + + readImage(xlink, &_images[_imageCount]); + + _imageCount++; + } + } + + _loaded = 1; + } + + for (int i = 0; i < _imageCount; i++) + { + try + { + Magick::Image effectedImage = _images[i]; + applyEffect(&effectedImage); + + Magick::Blob blob; + effectedImage.write(&blob); + + std::string raw_string = blob.base64(); + const int raw_len = raw_string.length(); + const char *raw = raw_string.c_str(); + const char *raw_i = raw; + + int formatted_len = (int)(raw_len / 76.0 * 78.0) + 100; + char *formatted = new char[formatted_len]; + char *formatted_i = formatted; + // data:image/png;base64, + formatted_i = stpcpy(formatted_i, "data:image/"); + formatted_i = stpcpy(formatted_i, effectedImage.magick().c_str()); + formatted_i = stpcpy(formatted_i, ";base64, \n"); + while (strnlen(raw_i, 80) > 76) + { + formatted_i = stpncpy(formatted_i, raw_i, 76); + formatted_i = stpcpy(formatted_i, "\n"); + raw_i += 76; + } + if (strlen(raw_i) > 0) + { + formatted_i = stpcpy(formatted_i, raw_i); + formatted_i = stpcpy(formatted_i, "\n"); + } + + formatted_i = stpcpy(formatted_i, "\0"); + + _nodes[i]->setAttribute("xlink:href", formatted, true); + } + catch (Magick::Exception &error_) { + printf("Caught exception: %s \n", error_.what()); + } + } +} + +/** \brief A function to get the prefences for the grid + \param moudule Module which holds the params + \param view Unused today - may get style information in the future. + + Uses AutoGUI for creating the GUI. +*/ +Gtk::Widget * +ImageMagick::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View * view, sigc::signal<void> * changeSignal) +{ + SPDocument * current_document = view->doc(); + + using Inkscape::Util::GSListConstIterator; + GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList(); + Inkscape::XML::Node * first_select = NULL; + if (selected != NULL) + first_select = SP_OBJECT_REPR(*selected); + + return module->autogui(current_document, first_select, changeSignal); +} + +}; /* namespace Bitmap */ +}; /* namespace Internal */ +}; /* namespace Extension */ +}; /* namespace Inkscape */ |
