diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp
index b7e83a979012358b1f9a5dac2b595e3ea5e72f26..d40fb89d7e67567b2e112c53ec1824e85c78d67f 100644 (file)
--- a/src/trace/trace.cpp
+++ b/src/trace/trace.cpp
#include "trace/potrace/inkscape-potrace.h"
#include <inkscape.h>
+#include <desktop.h>
#include <desktop-handles.h>
#include <document.h>
-#include "message-stack.h"
+#include <message-stack.h>
#include <glibmm/i18n.h>
#include <selection.h>
#include <xml/repr.h>
-#include "sp-item.h"
-#include "sp-image.h"
+#include <xml/attribute-record.h>
+#include <sp-item.h>
+#include <sp-shape.h>
+#include <sp-image.h>
+
+#include <display/nr-arena.h>
+#include <display/nr-arena-shape.h>
#include "siox.h"
#include "imagemap-gdk.h"
-namespace Inkscape {
-namespace Trace {
+
+namespace Inkscape
+{
+
+namespace Trace
+{
+
+
+
+
+
/**
- *
+ * Get the selected image. Also check for any SPItems over it, in
+ * case the user wants SIOX pre-processing.
*/
SPImage *
Tracer::getSelectedSPImage()
{
+
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (!desktop)
{
return NULL;
}
- Inkscape::Selection *sel = SP_DT_SELECTION(desktop);
+ Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop);
+
+ Inkscape::Selection *sel = sp_desktop_selection(desktop);
if (!sel)
{
char *msg = _("Select an <b>image</b> to trace");
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
//g_warning(msg);
return NULL;
}
{
SPImage *img = NULL;
GSList const *list = sel->itemList();
- sioxItems.clear();
std::vector<SPItem *> items;
+ sioxShapes.clear();
+
/*
First, things are selected top-to-bottom, so we need to invert
them as bottom-to-top so that we can discover the image and any
if (img) //we want only one
{
char *msg = _("Select only one <b>image</b> to trace");
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
return NULL;
}
img = SP_IMAGE(item);
}
- else if (img) //# items -after- the image in tree (above it in Z)
+ else // if (img) //# items -after- the image in tree (above it in Z)
{
- sioxItems.push_back(item);
+ if (SP_IS_SHAPE(item))
+ {
+ SPShape *shape = SP_SHAPE(item);
+ sioxShapes.push_back(shape);
+ }
}
}
- if (!img || sioxItems.size() < 1)
+
+ if (!img || sioxShapes.size() < 1)
{
- char *msg = _("Select one image and one or more items above it");
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+ char *msg = _("Select one image and one or more shapes above it");
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
return NULL;
}
return img;
}
else
- //### No SIOX. We want exactly one image selected
+ //### SIOX not enabled. We want exactly one image selected
{
SPItem *item = sel->singleItem();
if (!item)
{
char *msg = _("Select an <b>image</b> to trace"); //same as above
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
//g_warning(msg);
return NULL;
}
if (!SP_IS_IMAGE(item))
{
char *msg = _("Select an <b>image</b> to trace");
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
//g_warning(msg);
return NULL;
}
-/**
- *
- */
+typedef org::siox::SioxImage SioxImage;
+typedef org::siox::Siox Siox;
+
GdkPixbuf *
-Tracer::getSelectedImage()
+Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
{
+ if (!sioxEnabled)
+ return origPixbuf;
- SPImage *img = getSelectedSPImage();
- if (!img)
+ //Convert from gdk, so a format we know. By design, the pixel
+ //format in PackedPixelMap is identical to what is needed by SIOX
+ SioxImage simage(origPixbuf);
+
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (!desktop)
+ {
+ g_warning("Trace: No active desktop\n");
return NULL;
+ }
- GdkPixbuf *pixbuf = img->pixbuf;
+ Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop);
- return pixbuf;
+ Inkscape::Selection *sel = sp_desktop_selection(desktop);
+ if (!sel)
+ {
+ char *msg = _("Select an <b>image</b> to trace");
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
+ //g_warning(msg);
+ return NULL;
+ }
-}
+ NRArenaItem *aImg = sp_item_get_arenaitem(img, desktop->dkey);
+ //g_message("img: %d %d %d %d\n", aImg->bbox.x0, aImg->bbox.y0,
+ // aImg->bbox.x1, aImg->bbox.y1);
+ double width = (double)(aImg->bbox.x1 - aImg->bbox.x0);
+ double height = (double)(aImg->bbox.y1 - aImg->bbox.y0);
-GdkPixbuf *
-Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
-{
+ double iwidth = (double)simage.getWidth();
+ double iheight = (double)simage.getHeight();
+
+ double iwscale = width / iwidth;
+ double ihscale = height / iheight;
+
+ std::vector<NRArenaItem *> arenaItems;
+ std::vector<SPShape *>::iterator iter;
+ for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; iter++)
+ {
+ SPItem *item = *iter;
+ //### Create ArenaItems and set transform
+ NRArenaItem *aItem = sp_item_get_arenaitem(item, desktop->dkey);
+
+ //nr_arena_item_set_transform(aItem, item->transform);
+ //g_message("%d %d %d %d\n", aItem->bbox.x0, aItem->bbox.y0,
+ // aItem->bbox.x1, aItem->bbox.y1);
+ arenaItems.push_back(aItem);
+ }
+ //g_message("%d arena items\n", arenaItems.size());
- RgbMap *rgbMap = gdkPixbufToRgbMap(origPixbuf);
- //We need to create two things:
- // 1. An array of long pixel values of ARGB
- // 2. A matching array of per-pixel float 'confidence' values
- long *imgBuf = new long[rgbMap->width * rgbMap->height];
- float *confidenceMatrix = new float[rgbMap->width * rgbMap->height];
+ PackedPixelMap *dumpMap = PackedPixelMapCreate(
+ simage.getWidth(), simage.getHeight());
- long idx = 0;
- for (int j=0 ; j<rgbMap->height ; j++)
- for (int i=0 ; i<rgbMap->width ; i++)
+ for (int row=0 ; row<simage.getHeight() ; row++)
+ {
+ double ypos = ((double)aImg->bbox.y0) + ihscale * (double) row;
+ for (int col=0 ; col<simage.getWidth() ; col++)
{
- RGB rgb = rgbMap->getPixel(rgbMap, i, j);
- long pix = (((long)rgb.r) << 16 & 0xFF0000L) |
- (((long)rgb.g) << 8 & 0x00FF00L) |
- (((long)rgb.b) & 0x0000FFL);
- imgBuf[idx++] = pix;
+ //Get absolute X,Y position
+ double xpos = ((double)aImg->bbox.x0) + iwscale * (double)col;
+ NR::Point point(xpos, ypos);
+ point *= aImg->transform;
+ //point *= imgMat;
+ //point = desktop->doc2dt(point);
+ std::vector<SPShape *>::iterator iter;
+ //g_message("x:%f y:%f\n", point[0], point[1]);
+ bool weHaveAHit = false;
+ std::vector<NRArenaItem *>::iterator aIter;
+ for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++)
+ {
+ NRArenaItem *arenaItem = *aIter;
+ NRArenaItemClass *arenaClass =
+ (NRArenaItemClass *) NR_OBJECT_GET_CLASS (arenaItem);
+ if (arenaClass->pick(arenaItem, point, 1.0f, 1))
+ {
+ weHaveAHit = true;
+ break;
+ }
+ }
+
+ if (weHaveAHit)
+ {
+ //g_message("hit!\n");
+ dumpMap->setPixelLong(dumpMap, col, row, 0L);
+ simage.setConfidence(col, row,
+ Siox::UNKNOWN_REGION_CONFIDENCE);
+ }
+ else
+ {
+ dumpMap->setPixelLong(dumpMap, col, row,
+ simage.getPixel(col, row));
+ simage.setConfidence(col, row,
+ Siox::CERTAIN_BACKGROUND_CONFIDENCE);
+ }
}
+ }
+
+ //dumpMap->writePPM(dumpMap, "siox1.ppm");
+ dumpMap->destroy(dumpMap);
//## ok we have our pixel buf
- org::siox::SioxSegmentator ss(rgbMap->width, rgbMap->height, NULL, 0);
- ss.segmentate(imgBuf, rgbMap->width * rgbMap->height,
- confidenceMatrix, rgbMap->width * rgbMap->height,
- 0, 0.0);
-
- idx = 0;
- for (int j=0 ; j<rgbMap->height ; j++)
- for (int i=0 ; i<rgbMap->width ; i++)
- {
- long pix = imgBuf[idx++];
- RGB rgb;
- rgb.r = (pix>>16) & 0xff;
- rgb.g = (pix>> 8) & 0xff;
- rgb.b = (pix ) & 0xff;
- rgbMap->setPixelRGB(rgbMap, i, j, rgb);
- }
+ org::siox::Siox sengine;
+ org::siox::SioxImage result =
+ sengine.extractForeground(simage, 0xffffff);
+ if (!result.isValid())
+ {
+ g_warning("Invalid SIOX result");
+ return NULL;
+ }
- GdkPixbuf *newPixbuf = rgbMapToGdkPixbuf(rgbMap);
- rgbMap->destroy(rgbMap);
- delete imgBuf;
- delete confidenceMatrix;
+ //result.writePPM("siox2.ppm");
+
+ /* Free Arena and ArenaItem */
+ /*
+ std::vector<NRArenaItem *>::iterator aIter;
+ for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++)
+ {
+ NRArenaItem *arenaItem = *aIter;
+ nr_arena_item_unref(arenaItem);
+ }
+ nr_object_unref((NRObject *) arena);
+ */
+
+ GdkPixbuf *newPixbuf = result.getGdkPixbuf();
return newPixbuf;
}
+/**
+ *
+ */
+GdkPixbuf *
+Tracer::getSelectedImage()
+{
+
+ SPImage *img = getSelectedSPImage();
+ if (!img)
+ return NULL;
+
+ GdkPixbuf *pixbuf = img->pixbuf;
+ if (!pixbuf)
+ return NULL;
+
+ if (sioxEnabled)
+ {
+ GdkPixbuf *sioxPixbuf = sioxProcessImage(img, pixbuf);
+ if (!sioxPixbuf)
+ {
+ g_object_ref(pixbuf);
+ return pixbuf;
+ }
+ else
+ {
+ return sioxPixbuf;
+ }
+ }
+ else
+ {
+ g_object_ref(pixbuf);
+ return pixbuf;
+ }
+
+}
+
//#########################################################################
return;
}
- Inkscape::Selection *selection = SP_DT_SELECTION (desktop);
+ Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop);
+
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
if (!SP_ACTIVE_DOCUMENT)
{
char *msg = _("Trace: No active document");
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
//g_warning(msg);
engine = NULL;
return;
}
GdkPixbuf *pixbuf = img->pixbuf;
+ g_object_ref(pixbuf);
+
+ pixbuf = sioxProcessImage(img, pixbuf);
if (!pixbuf)
{
char *msg = _("Trace: Image has no bitmap data");
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, msg);
+ msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
//g_warning(msg);
engine = NULL;
return;
}
- //## SIOX pre-processing to get a smart subimage of the pixbuf.
- //## This is done before any other filters
- if (sioxEnabled)
- {
- /*
- Ok, we have requested siox, and getSelectedSPImage() has found a single
- bitmap and one or more SPItems above it. Now what we need to do is create
- a siox-segmented subimage pixbuf. We not need alter 'img' at all, since this
- pixbuf will be the same dimensions and at the same location.
- Remember to free this new pixbuf later.
- */
- pixbuf = sioxProcessImage(img, pixbuf);
- }
-
int nrPaths;
TracingEngineResult *results = engine->trace(pixbuf, &nrPaths);
//printf("nrPaths:%d\n", nrPaths);
Inkscape::GC::release(pathRepr);
}
- //did we allocate a pixbuf copy?
- if (sioxEnabled)
- {
- g_free(pixbuf);
- }
+ //release our pixbuf
+ g_object_unref(pixbuf);
delete results;
engine = NULL;
char *msg = g_strdup_printf(_("Trace: Done. %ld nodes created"), totalNodeCount);
- SP_DT_MSGSTACK(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg);
+ msgStack->flash(Inkscape::NORMAL_MESSAGE, msg);
g_free(msg);
}