On Tuesday, 5 Dec 2000, David Bonnell wrote:

> On Wed, 6 Dec 2000, Austin Donnelly wrote:
> 
> > ...
> > Probably the easiest way would be to use select by colour, but that
> > would catch other stuff that was a similar colour.
> >
> Could change "Select by Colour" to only select pixels within the current
> selection if there is one, or the entire image (or layer) if there
> isn't an active selection.
> 
> > With this, you could lasso the general area the text is in, then go
> > <Image>/Selection/Tighten to get just your text.
> >
> That would certainly be a very useful tool.

Oops.  I accidentally implemented it.

Patch against 1.1.29 attached below.

It needs some work:
 o The algorithm to find the start point for the seed fill is pretty
   dumb: it picks the topmost image pixel in the selection, and flood
   fills from there.  Plus its a really inefficient implementation of
   this brain dead algorithm.

 o No PDB access functions.

 o No help file.

 o No way to tweak edge detection threshold
 o No way to set sample merged, so it only works on the current layer
    (These last two are because it has no UI.  I don't think it should
     have a UI since it's supposed to be quick and just do the right
     thing.  Mostly it does.)

If anyone feels like playing with it, let me know how you get on.
I think it's pretty cool (but then I'm biased).

Austin
--- commands.c~ Mon Oct 30 01:33:11 2000
+++ commands.c  Wed Dec  6 17:05:24 2000
@@ -390,6 +390,19 @@
   gtk_widget_show (shrink_dialog);
 }
 
+
+void
+select_tighten_cmd_callback (GtkWidget *widget,
+                            gpointer   client_data)
+{
+  GDisplay *gdisp;
+  return_if_no_display (gdisp);
+
+  gimage_mask_tighten (gdisp->gimage);
+  gdisplays_flush ();  
+}
+
+
 void
 select_grow_cmd_callback (GtkWidget *widget,
                          gpointer   client_data)
--- commands.h~ Mon Oct 30 01:33:11 2000
+++ commands.h  Wed Dec  6 17:25:14 2000
@@ -52,6 +52,7 @@
 void select_feather_cmd_callback  (GtkWidget *, gpointer);
 void select_sharpen_cmd_callback  (GtkWidget *, gpointer);
 void select_shrink_cmd_callback   (GtkWidget *, gpointer);
+void select_tighten_cmd_callback  (GtkWidget *, gpointer);
 void select_border_cmd_callback   (GtkWidget *, gpointer);
 void select_grow_cmd_callback     (GtkWidget *, gpointer);
 void select_save_cmd_callback     (GtkWidget *, gpointer);
--- gimage_mask.c~      Mon Oct 30 01:33:14 2000
+++ gimage_mask.c       Wed Dec  6 18:06:40 2000
@@ -22,6 +22,7 @@
 #include "floating_sel.h"
 #include "gdisplay.h"
 #include "gimage_mask.h"
+#include "fuzzy_select.h"
 #include "gimprc.h"
 #include "layer.h"
 #include "paint_core.h"
@@ -478,6 +479,55 @@
                  edge_lock);
 }
 
+
+void
+gimage_mask_tighten (GImage  *gimage)
+{
+  Channel *mask;
+  Channel *shrinkage;
+  GimpDrawable *drawable;
+  gint x1, y1, x2, y2;
+  gint x;
+
+  g_return_if_fail (gimage != NULL);
+  drawable = gimage_active_drawable (gimage);
+  g_return_if_fail (drawable != NULL);
+
+  mask = gimage_get_mask (gimage);
+  g_return_if_fail (mask != NULL);
+
+  undo_push_group_start (gimage, MASK_UNDO);
+
+  channel_push_undo (mask);
+
+  /* if there was no selection, then assume the entire image was selected */
+  if (channel_is_empty (mask))
+      channel_all (mask);
+
+  /* Pick a point within the selection from which to start the seed
+   * fill. */
+  channel_bounds (mask, &x1, &y1, &x2, &y2);
+  x = x1;
+  /* XXX FIXME: seriously costly loop: should do pixel iteration
+   * ourselves */
+  while (x < x2 && channel_value (mask, x, y1) < 128)
+      x++;
+
+  /* XXX Need to find some way of presenting the threshold and sample
+   * merged options to the user, without getting in their way. */
+  shrinkage = find_contiguous_region (gimage, drawable,
+                                     /* antialias */ TRUE,
+                                     /* threshold */ 15,
+                                     x, y1,
+                                     /* sample merged */ 0);
+  channel_combine_mask (mask, shrinkage, SUB, 0, 0);
+  channel_delete (shrinkage);
+
+  gimage_mask_invalidate (gimage);
+
+  undo_push_group_end (gimage);
+}
+                    
 
 void
 gimage_mask_layer_alpha (GImage *gimage,
--- gimage_mask.h~      Mon Oct 30 01:33:14 2000
+++ gimage_mask.h       Wed Dec  6 17:29:56 2000
@@ -81,6 +81,8 @@
                                           gint          shrink_pixels_y,
                                           gboolean      edge_lock);
 
+void            gimage_mask_tighten       (GImage       *gimage);
+
 void            gimage_mask_layer_alpha   (GImage       *gimage,
                                           Layer        *layer);
 
--- menus.c~    Mon Oct 30 01:33:22 2000
+++ menus.c     Wed Dec  6 17:24:42 2000
@@ -285,6 +285,8 @@
     "select/sharpen.html", NULL },
   { { N_("/Select/Shrink..."), NULL, select_shrink_cmd_callback, 0 },
     "select/dialogs/shrink_selection.html", NULL },
+  { { N_("/Select/Tighten"), NULL, select_tighten_cmd_callback, 0 } ,
+    "select/dialogs/tighten_selection.html", NULL },
   { { N_("/Select/Grow..."), NULL, select_grow_cmd_callback, 0 },
     "select/dialogs/grow_selection.html", NULL },
   { { N_("/Select/Border..."), "<control><shift>B", select_border_cmd_callback, 0 },

Reply via email to