[gimp] app, pdb, libgimp: allow to choose the channel when thresholding
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app, pdb, libgimp: allow to choose the channel when thresholding
- Date: Tue, 1 Nov 2016 22:29:22 +0000 (UTC)
commit 3cef404e20c58fbbd2f7c95fb7e4055fdf38f594
Author: Michael Natterer <mitch gimp org>
Date: Tue Nov 1 22:41:56 2016 +0100
app, pdb, libgimp: allow to choose the channel when thresholding
so the threshold can now be based on the GimpHistogramChannel enum.
Add a channel menu to the threshold dialog and a channel argument to
the PDB procedure (which is new in 2.10).
If I hadn't forgotten what the "RGB" channel is supposed to do I would
have implemented the RGB mode in GimpOperationThreshold correctly.
Right now I'm just guessing. Anyone?
app/operations/gimpoperationthreshold.c | 56 ++++++++++-
app/operations/gimpoperationthreshold.h | 1 +
app/pdb/drawable-color-cmds.c | 16 +++-
app/tools/gimpthresholdtool.c | 162 +++++++++++++++++++++++-------
app/tools/gimpthresholdtool.h | 1 +
libgimp/gimpdrawablecolor_pdb.c | 13 ++-
libgimp/gimpdrawablecolor_pdb.h | 1 +
tools/pdbgen/pdb/drawable_color.pdb | 7 +-
8 files changed, 205 insertions(+), 52 deletions(-)
---
diff --git a/app/operations/gimpoperationthreshold.c b/app/operations/gimpoperationthreshold.c
index 0282af8..ddcd517 100644
--- a/app/operations/gimpoperationthreshold.c
+++ b/app/operations/gimpoperationthreshold.c
@@ -24,6 +24,7 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
+#include "libgimpcolor/gimpcolor.h"
#include "libgimpconfig/gimpconfig.h"
#include "operations-types.h"
@@ -36,6 +37,7 @@
enum
{
PROP_0,
+ PROP_CHANNEL,
PROP_LOW,
PROP_HIGH
};
@@ -82,6 +84,14 @@ gimp_operation_threshold_class_init (GimpOperationThresholdClass *klass)
"description", "GIMP Threshold operation",
NULL);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_CHANNEL,
+ "channel",
+ _("Channel"),
+ NULL,
+ GIMP_TYPE_HISTOGRAM_CHANNEL,
+ GIMP_HISTOGRAM_VALUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_LOW,
"low",
_("Low threshold"),
@@ -112,6 +122,10 @@ gimp_operation_threshold_get_property (GObject *object,
switch (property_id)
{
+ case PROP_CHANNEL:
+ g_value_set_enum (value, self->channel);
+ break;
+
case PROP_LOW:
g_value_set_double (value, self->low);
break;
@@ -136,6 +150,10 @@ gimp_operation_threshold_set_property (GObject *object,
switch (property_id)
{
+ case PROP_CHANNEL:
+ self->channel = g_value_get_enum (value);
+ break;
+
case PROP_LOW:
self->low = g_value_get_double (value);
break;
@@ -164,10 +182,40 @@ gimp_operation_threshold_process (GeglOperation *operation,
while (samples--)
{
- gfloat value;
-
- value = MAX (src[RED], src[GREEN]);
- value = MAX (value, src[BLUE]);
+ gfloat value = 0.0;
+
+ switch (threshold->channel)
+ {
+ case GIMP_HISTOGRAM_VALUE:
+ value = MAX (src[RED], src[GREEN]);
+ value = MAX (value, src[BLUE]);
+ break;
+
+ case GIMP_HISTOGRAM_RED:
+ value = src[RED];
+ break;
+
+ case GIMP_HISTOGRAM_GREEN:
+ value = src[GREEN];
+ break;
+
+ case GIMP_HISTOGRAM_BLUE:
+ value = src[BLUE];
+ break;
+
+ case GIMP_HISTOGRAM_ALPHA:
+ value = src[ALPHA];
+ break;
+
+ case GIMP_HISTOGRAM_RGB:
+ value = MIN (src[RED], src[GREEN]);
+ value = MIN (value, src[BLUE]);
+ break;
+
+ case GIMP_HISTOGRAM_LUMINANCE:
+ value = GIMP_RGB_LUMINANCE (src[RED], src[GREEN], src[BLUE]);
+ break;
+ }
value = (value >= threshold->low && value <= threshold->high) ? 1.0 : 0.0;
diff --git a/app/operations/gimpoperationthreshold.h b/app/operations/gimpoperationthreshold.h
index d4f82ee..30bc165 100644
--- a/app/operations/gimpoperationthreshold.h
+++ b/app/operations/gimpoperationthreshold.h
@@ -40,6 +40,7 @@ struct _GimpOperationThreshold
{
GimpOperationPointFilter parent_instance;
+ GimpHistogramChannel channel;
gdouble low;
gdouble high;
};
diff --git a/app/pdb/drawable-color-cmds.c b/app/pdb/drawable-color-cmds.c
index b73ee24..d0011d7 100644
--- a/app/pdb/drawable-color-cmds.c
+++ b/app/pdb/drawable-color-cmds.c
@@ -679,12 +679,14 @@ drawable_threshold_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
+ gint32 channel;
gdouble low_threshold;
gdouble high_threshold;
drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
- low_threshold = g_value_get_double (gimp_value_array_index (args, 1));
- high_threshold = g_value_get_double (gimp_value_array_index (args, 2));
+ channel = g_value_get_enum (gimp_value_array_index (args, 1));
+ low_threshold = g_value_get_double (gimp_value_array_index (args, 2));
+ high_threshold = g_value_get_double (gimp_value_array_index (args, 3));
if (success)
{
@@ -695,6 +697,7 @@ drawable_threshold_invoker (GimpProcedure *procedure,
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "gimp:threshold",
+ "channel", channel,
"low", low_threshold,
"high", high_threshold,
NULL);
@@ -1264,7 +1267,7 @@ register_drawable_color_procs (GimpPDB *pdb)
gimp_procedure_set_static_strings (procedure,
"gimp-drawable-threshold",
"Threshold the specified drawable.",
- "This procedures generates a threshold map of the specified drawable.
All pixels between the values of 'low_threshold' and 'high_threshold' are replaced with white, and all other
pixels with black.",
+ "This procedures generates a threshold map of the specified drawable.
All pixels between the values of 'low_threshold' and 'high_threshold', on the scale of 'channel' are replaced
with white, and all other pixels with black.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1997",
@@ -1276,6 +1279,13 @@ register_drawable_color_procs (GimpPDB *pdb)
pdb->gimp, FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
+ g_param_spec_enum ("channel",
+ "channel",
+ "The channel to base the threshold on",
+ GIMP_TYPE_HISTOGRAM_CHANNEL,
+ GIMP_HISTOGRAM_VALUE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
g_param_spec_double ("low-threshold",
"low threshold",
"The low threshold value",
diff --git a/app/tools/gimpthresholdtool.c b/app/tools/gimpthresholdtool.c
index 10429e4..da85ece 100644
--- a/app/tools/gimpthresholdtool.c
+++ b/app/tools/gimpthresholdtool.c
@@ -64,6 +64,9 @@ static void gimp_threshold_tool_config_notify (GObject *object
GParamSpec *pspec,
GimpThresholdTool *t_tool);
+static gboolean gimp_threshold_tool_channel_sensitive
+ (gint value,
+ gpointer data);
static void gimp_threshold_tool_histogram_range (GimpHistogramView *view,
gint start,
gint end,
@@ -159,6 +162,10 @@ gimp_threshold_tool_initialize (GimpTool *tool,
return FALSE;
}
+ gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (t_tool->channel_menu),
+ gimp_threshold_tool_channel_sensitive,
+ drawable, NULL);
+
gimp_drawable_calculate_histogram (drawable, t_tool->histogram);
gimp_histogram_view_set_histogram (t_tool->histogram_box->view,
t_tool->histogram);
@@ -187,42 +194,72 @@ gimp_threshold_tool_get_operation (GimpFilterTool *filter_tool,
static void
gimp_threshold_tool_dialog (GimpFilterTool *filter_tool)
{
- GimpThresholdTool *t_tool = GIMP_THRESHOLD_TOOL (filter_tool);
- GimpToolOptions *tool_options = GIMP_TOOL_GET_OPTIONS (filter_tool);
- GtkWidget *main_vbox;
- GtkWidget *hbox;
- GtkWidget *menu;
- GtkWidget *box;
- GtkWidget *button;
- gdouble low;
- gdouble high;
- gint n_bins;
+ GimpThresholdTool *t_tool = GIMP_THRESHOLD_TOOL (filter_tool);
+ GimpToolOptions *tool_options = GIMP_TOOL_GET_OPTIONS (filter_tool);
+ GtkWidget *main_vbox;
+ GtkWidget *main_frame;
+ GtkWidget *frame_vbox;
+ GtkWidget *hbox;
+ GtkWidget *label;
+ GtkWidget *hbox2;
+ GtkWidget *box;
+ GtkWidget *button;
+ GimpHistogramChannel channel;
+ gdouble low;
+ gdouble high;
+ gint n_bins;
main_vbox = gimp_filter_tool_dialog_get_vbox (filter_tool);
+ main_frame = gimp_frame_new (NULL);
+ gtk_box_pack_start (GTK_BOX (main_vbox), main_frame, TRUE, TRUE, 0);
+ gtk_widget_show (main_frame);
+
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
+ gtk_frame_set_label_widget (GTK_FRAME (main_frame), hbox);
gtk_widget_show (hbox);
- menu = gimp_prop_enum_icon_box_new (G_OBJECT (tool_options),
- "histogram-scale", "gimp-histogram",
- 0, 0);
- gtk_box_pack_end (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
- gtk_widget_show (menu);
+ label = gtk_label_new_with_mnemonic (_("Cha_nnel:"));
+ gimp_label_set_attributes (GTK_LABEL (label),
+ PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
+ -1);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ t_tool->channel_menu = gimp_prop_enum_combo_box_new (filter_tool->config,
+ "channel", -1, -1);
+ gimp_enum_combo_box_set_icon_prefix (GIMP_ENUM_COMBO_BOX (t_tool->channel_menu),
+ "gimp-channel");
+ gtk_box_pack_start (GTK_BOX (hbox), t_tool->channel_menu, FALSE, FALSE, 0);
+ gtk_widget_show (t_tool->channel_menu);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), t_tool->channel_menu);
+
+ hbox2 = gimp_prop_enum_icon_box_new (G_OBJECT (tool_options),
+ "histogram-scale", "gimp-histogram",
+ 0, 0);
+ gtk_box_pack_end (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
+ gtk_widget_show (hbox2);
+
+ frame_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
+ gtk_container_add (GTK_CONTAINER (main_frame), frame_vbox);
+ gtk_widget_show (frame_vbox);
box = gimp_histogram_box_new ();
- gtk_box_pack_start (GTK_BOX (main_vbox), box, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (frame_vbox), box, TRUE, TRUE, 0);
gtk_widget_show (box);
t_tool->histogram_box = GIMP_HISTOGRAM_BOX (box);
g_object_get (filter_tool->config,
- "low", &low,
- "high", &high,
+ "channel", &channel,
+ "low", &low,
+ "high", &high,
NULL);
n_bins = gimp_histogram_n_bins (t_tool->histogram);
+ gimp_histogram_view_set_channel (t_tool->histogram_box->view, channel);
gimp_histogram_view_set_range (t_tool->histogram_box->view,
low * (n_bins - 0.0001),
high * (n_bins - 0.0001));
@@ -237,7 +274,7 @@ gimp_threshold_tool_dialog (GimpFilterTool *filter_tool)
G_BINDING_BIDIRECTIONAL);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (frame_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
button = gtk_button_new_with_mnemonic (_("_Auto"));
@@ -256,23 +293,68 @@ gimp_threshold_tool_config_notify (GObject *object,
GParamSpec *pspec,
GimpThresholdTool *t_tool)
{
- gdouble low;
- gdouble high;
- gint n_bins;
-
if (! t_tool->histogram_box)
return;
- g_object_get (object,
- "low", &low,
- "high", &high,
- NULL);
+ if (! strcmp (pspec->name, "channel"))
+ {
+ GimpHistogramChannel channel;
- n_bins = gimp_histogram_n_bins (t_tool->histogram);
+ g_object_get (object,
+ "channel", &channel,
+ NULL);
- gimp_histogram_view_set_range (t_tool->histogram_box->view,
- low * (n_bins - 0.0001),
- high * (n_bins - 0.0001));
+ gimp_histogram_view_set_channel (t_tool->histogram_box->view,
+ channel);
+ }
+ else if (! strcmp (pspec->name, "low") ||
+ ! strcmp (pspec->name, "high"))
+ {
+ gdouble low;
+ gdouble high;
+ gint n_bins;
+
+ g_object_get (object,
+ "low", &low,
+ "high", &high,
+ NULL);
+
+ n_bins = gimp_histogram_n_bins (t_tool->histogram);
+
+ gimp_histogram_view_set_range (t_tool->histogram_box->view,
+ low * (n_bins - 0.0001),
+ high * (n_bins - 0.0001));
+ }
+}
+
+static gboolean
+gimp_threshold_tool_channel_sensitive (gint value,
+ gpointer data)
+{
+ GimpDrawable *drawable = GIMP_DRAWABLE (data);
+ GimpHistogramChannel channel = value;
+
+ switch (channel)
+ {
+ case GIMP_HISTOGRAM_VALUE:
+ return TRUE;
+
+ case GIMP_HISTOGRAM_RED:
+ case GIMP_HISTOGRAM_GREEN:
+ case GIMP_HISTOGRAM_BLUE:
+ return gimp_drawable_is_rgb (drawable);
+
+ case GIMP_HISTOGRAM_ALPHA:
+ return gimp_drawable_has_alpha (drawable);
+
+ case GIMP_HISTOGRAM_RGB:
+ return gimp_drawable_is_rgb (drawable);
+
+ case GIMP_HISTOGRAM_LUMINANCE:
+ return gimp_drawable_is_rgb (drawable);
+ }
+
+ return FALSE;
}
static void
@@ -307,14 +389,18 @@ static void
gimp_threshold_tool_auto_clicked (GtkWidget *button,
GimpThresholdTool *t_tool)
{
- GimpDrawable *drawable = GIMP_FILTER_TOOL (t_tool)->drawable;
- gint n_bins = gimp_histogram_n_bins (t_tool->histogram);
- gdouble low;
+ GimpHistogramChannel channel;
+ gint n_bins;
+ gdouble low;
+
+ g_object_get (GIMP_FILTER_TOOL (t_tool)->config,
+ "channel", &channel,
+ NULL);
+
+ n_bins = gimp_histogram_n_bins (t_tool->histogram);
low = gimp_histogram_get_threshold (t_tool->histogram,
- gimp_drawable_is_rgb (drawable) ?
- GIMP_HISTOGRAM_RGB :
- GIMP_HISTOGRAM_VALUE,
+ channel,
0, n_bins - 1);
gimp_histogram_view_set_range (t_tool->histogram_box->view,
diff --git a/app/tools/gimpthresholdtool.h b/app/tools/gimpthresholdtool.h
index 6e4f7dc..4eca23a 100644
--- a/app/tools/gimpthresholdtool.h
+++ b/app/tools/gimpthresholdtool.h
@@ -39,6 +39,7 @@ struct _GimpThresholdTool
/* dialog */
GimpHistogram *histogram;
+ GtkWidget *channel_menu;
GimpHistogramBox *histogram_box;
};
diff --git a/libgimp/gimpdrawablecolor_pdb.c b/libgimp/gimpdrawablecolor_pdb.c
index 6c6ea40..7541d49 100644
--- a/libgimp/gimpdrawablecolor_pdb.c
+++ b/libgimp/gimpdrawablecolor_pdb.c
@@ -635,6 +635,7 @@ gimp_drawable_posterize (gint32 drawable_ID,
/**
* gimp_drawable_threshold:
* @drawable_ID: The drawable.
+ * @channel: The channel to base the threshold on.
* @low_threshold: The low threshold value.
* @high_threshold: The high threshold value.
*
@@ -642,17 +643,18 @@ gimp_drawable_posterize (gint32 drawable_ID,
*
* This procedures generates a threshold map of the specified drawable.
* All pixels between the values of 'low_threshold' and
- * 'high_threshold' are replaced with white, and all other pixels with
- * black.
+ * 'high_threshold', on the scale of 'channel' are replaced with white,
+ * and all other pixels with black.
*
* Returns: TRUE on success.
*
* Since: 2.10
**/
gboolean
-gimp_drawable_threshold (gint32 drawable_ID,
- gdouble low_threshold,
- gdouble high_threshold)
+gimp_drawable_threshold (gint32 drawable_ID,
+ GimpHistogramChannel channel,
+ gdouble low_threshold,
+ gdouble high_threshold)
{
GimpParam *return_vals;
gint nreturn_vals;
@@ -661,6 +663,7 @@ gimp_drawable_threshold (gint32 drawable_ID,
return_vals = gimp_run_procedure ("gimp-drawable-threshold",
&nreturn_vals,
GIMP_PDB_DRAWABLE, drawable_ID,
+ GIMP_PDB_INT32, channel,
GIMP_PDB_FLOAT, low_threshold,
GIMP_PDB_FLOAT, high_threshold,
GIMP_PDB_END);
diff --git a/libgimp/gimpdrawablecolor_pdb.h b/libgimp/gimpdrawablecolor_pdb.h
index b8e138e..a30f1dd 100644
--- a/libgimp/gimpdrawablecolor_pdb.h
+++ b/libgimp/gimpdrawablecolor_pdb.h
@@ -85,6 +85,7 @@ gboolean gimp_drawable_levels_stretch (gint32 drawable_ID);
gboolean gimp_drawable_posterize (gint32 drawable_ID,
gint levels);
gboolean gimp_drawable_threshold (gint32 drawable_ID,
+ GimpHistogramChannel channel,
gdouble low_threshold,
gdouble high_threshold);
diff --git a/tools/pdbgen/pdb/drawable_color.pdb b/tools/pdbgen/pdb/drawable_color.pdb
index c825b6a..960289d 100644
--- a/tools/pdbgen/pdb/drawable_color.pdb
+++ b/tools/pdbgen/pdb/drawable_color.pdb
@@ -742,8 +742,8 @@ sub drawable_threshold {
$help = <<'HELP';
This procedures generates a threshold map of the specified
drawable. All pixels between the values of 'low_threshold' and
-'high_threshold' are replaced with white, and all other pixels with
-black.
+'high_threshold', on the scale of 'channel' are replaced with white,
+and all other pixels with black.
HELP
&std_pdb_misc;
@@ -753,6 +753,8 @@ HELP
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
+ { name => 'channel', type => 'enum GimpHistogramChannel',
+ desc => 'The channel to base the threshold on' },
{ name => 'low_threshold', type => '0.0 <= float <= 1.0',
desc => 'The low threshold value' },
{ name => 'high_threshold', type => '0.0 <= float <= 1.0',
@@ -769,6 +771,7 @@ HELP
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "gimp:threshold",
+ "channel", channel,
"low", low_threshold,
"high", high_threshold,
NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]