Beispiel #1
0
static void
gimp_threshold_tool_auto_clicked (GtkWidget         *button,
                                  GimpThresholdTool *t_tool)
{
  GimpTool     *tool = GIMP_TOOL (t_tool);
  GimpWaitable *waitable;

  waitable = gimp_trivially_cancelable_waitable_new (
    GIMP_WAITABLE (t_tool->histogram_async));

  gimp_wait (tool->tool_info->gimp, waitable, _("Calculating histogram..."));

  g_object_unref (waitable);

  if (gimp_async_is_synced   (t_tool->histogram_async) &&
      gimp_async_is_finished (t_tool->histogram_async))
    {
      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,
                                          channel,
                                          0, n_bins - 1);

      gimp_histogram_view_set_range (t_tool->histogram_box->view,
                                     low, n_bins - 1);
    }
}
Beispiel #2
0
static void
gimp_threshold_tool_histogram_range (GimpHistogramView *widget,
                                     gint               start,
                                     gint               end,
                                     GimpThresholdTool *t_tool)
{
  GimpFilterTool *filter_tool = GIMP_FILTER_TOOL (t_tool);
  gint            n_bins      = gimp_histogram_n_bins (t_tool->histogram);
  gdouble         low         = (gdouble) start / (n_bins - 1);
  gdouble         high        = (gdouble) end   / (n_bins - 1);
  gdouble         config_low;
  gdouble         config_high;

  g_object_get (filter_tool->config,
                "low",  &config_low,
                "high", &config_high,
                NULL);

  if (low  != config_low ||
      high != config_high)
    {
      g_object_set (filter_tool->config,
                    "low",  low,
                    "high", high,
                    NULL);
    }
}
Beispiel #3
0
static void
gimp_threshold_tool_dialog (GimpImageMapTool *image_map_tool)
{
    GimpThresholdTool   *t_tool       = GIMP_THRESHOLD_TOOL (image_map_tool);
    GimpToolOptions     *tool_options = GIMP_TOOL_GET_OPTIONS (image_map_tool);
    GimpThresholdConfig *config       = t_tool->config;
    GtkWidget           *main_vbox;
    GtkWidget           *hbox;
    GtkWidget           *menu;
    GtkWidget           *box;
    GtkWidget           *button;
    gint                 n_bins;

    main_vbox = gimp_image_map_tool_dialog_get_vbox (image_map_tool);

    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
    gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
    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);

    box = gimp_histogram_box_new ();
    gtk_box_pack_start (GTK_BOX (main_vbox), box, TRUE, TRUE, 0);
    gtk_widget_show (box);

    t_tool->histogram_box = GIMP_HISTOGRAM_BOX (box);

    n_bins = gimp_histogram_n_bins (t_tool->histogram);

    gimp_histogram_view_set_range (t_tool->histogram_box->view,
                                   config->low  * (n_bins - 0.0001),
                                   config->high * (n_bins - 0.0001));

    g_signal_connect (t_tool->histogram_box->view, "range-changed",
                      G_CALLBACK (gimp_threshold_tool_histogram_range),
                      t_tool);

    gimp_histogram_options_connect_view (GIMP_HISTOGRAM_OPTIONS (tool_options),
                                         t_tool->histogram_box->view);

    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
    gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
    gtk_widget_show (hbox);

    button = gtk_button_new_with_mnemonic (_("_Auto"));
    gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
    gimp_help_set_help_data (button, _("Automatically adjust to optimal "
                                       "binarization threshold"), NULL);
    gtk_widget_show (button);

    g_signal_connect (button, "clicked",
                      G_CALLBACK (gimp_threshold_tool_auto_clicked),
                      t_tool);
}
Beispiel #4
0
static gboolean
gimp_threshold_tool_initialize (GimpTool     *tool,
                                GimpDisplay  *display,
                                GError      **error)
{
  GimpThresholdTool *t_tool      = GIMP_THRESHOLD_TOOL (tool);
  GimpFilterTool    *filter_tool = GIMP_FILTER_TOOL (tool);
  GimpImage         *image       = gimp_display_get_image (display);
  GimpDrawable      *drawable    = gimp_image_get_active_drawable (image);
  gdouble            low;
  gdouble            high;
  gint               n_bins;

  if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error))
    {
      return FALSE;
    }

  g_clear_object (&t_tool->histogram_async);

  g_object_get (filter_tool->config,
                "low",  &low,
                "high", &high,
                NULL);

  /* this is a hack to make sure that
   * 'gimp_histogram_n_bins (t_tool->histogram)' returns the correct value for
   * 'drawable' before the asynchronous calculation of its histogram is
   * finished.
   */
  {
    GeglBuffer *temp;

    temp = gegl_buffer_new (GEGL_RECTANGLE (0, 0, 1, 1),
                            gimp_drawable_get_format (drawable));

    gimp_histogram_calculate (t_tool->histogram,
                              temp, GEGL_RECTANGLE (0, 0, 1, 1),
                              NULL, NULL);

    g_object_unref (temp);
  }

  n_bins = gimp_histogram_n_bins (t_tool->histogram);

  t_tool->histogram_async = gimp_drawable_calculate_histogram_async (
    drawable, t_tool->histogram, FALSE);
  gimp_histogram_view_set_histogram (t_tool->histogram_box->view,
                                     t_tool->histogram);

  gimp_histogram_view_set_range (t_tool->histogram_box->view,
                                 low  * (n_bins - 0.0001),
                                 high * (n_bins - 0.0001));

  return TRUE;
}
static void
gimp_histogram_editor_info_update (GimpHistogramEditor *editor)
{
  GimpHistogramView *view = GIMP_HISTOGRAM_BOX (editor->box)->view;
  GimpHistogram     *hist = editor->histogram;

  if (hist)
    {
      gint    n_bins;
      gdouble pixels;
      gdouble count;
      gchar   text[12];

      n_bins = gimp_histogram_n_bins (hist);

      pixels = gimp_histogram_get_count (hist, view->channel, 0, n_bins - 1);
      count  = gimp_histogram_get_count (hist, view->channel,
                                         view->start, view->end);

      g_snprintf (text, sizeof (text), "%.3f",
                  gimp_histogram_get_mean (hist, view->channel,
                                           view->start, view->end));
      gtk_label_set_text (GTK_LABEL (editor->labels[0]), text);

      g_snprintf (text, sizeof (text), "%.3f",
                  gimp_histogram_get_std_dev (hist, view->channel,
                                              view->start, view->end));
      gtk_label_set_text (GTK_LABEL (editor->labels[1]), text);

      g_snprintf (text, sizeof (text), "%.3f",
                  gimp_histogram_get_median  (hist, view->channel,
                                              view->start,
                                              view->end));
      gtk_label_set_text (GTK_LABEL (editor->labels[2]), text);

      g_snprintf (text, sizeof (text), "%d", (gint) pixels);
      gtk_label_set_text (GTK_LABEL (editor->labels[3]), text);

      g_snprintf (text, sizeof (text), "%d", (gint) count);
      gtk_label_set_text (GTK_LABEL (editor->labels[4]), text);

      g_snprintf (text, sizeof (text), "%.1f", (pixels > 0 ?
                                                 (100.0 * count / pixels) :
                                                 0.0));
      gtk_label_set_text (GTK_LABEL (editor->labels[5]), text);
    }
  else
    {
      gint i;

      for (i = 0; i < 6; i++)
        gtk_label_set_text (GTK_LABEL (editor->labels[i]), NULL);
    }
}
Beispiel #6
0
static void
gimp_threshold_tool_auto_clicked (GtkWidget         *button,
                                  GimpThresholdTool *t_tool)
{
    GimpDrawable *drawable = GIMP_IMAGE_MAP_TOOL (t_tool)->drawable;
    gint          n_bins   = gimp_histogram_n_bins (t_tool->histogram);
    gdouble       low;

    low = gimp_histogram_get_threshold (t_tool->histogram,
                                        gimp_drawable_is_rgb (drawable) ?
                                        GIMP_HISTOGRAM_RGB :
                                        GIMP_HISTOGRAM_VALUE,
                                        0, n_bins - 1);

    gimp_histogram_view_set_range (t_tool->histogram_box->view,
                                   low, n_bins - 1);
}
Beispiel #7
0
static void
gimp_threshold_tool_config_notify (GObject           *object,
                                   GParamSpec        *pspec,
                                   GimpThresholdTool *t_tool)
{
    GimpThresholdConfig *config = GIMP_THRESHOLD_CONFIG (object);
    gint                 n_bins;

    if (! t_tool->histogram_box)
        return;

    n_bins = gimp_histogram_n_bins (t_tool->histogram);

    gimp_histogram_view_set_range (t_tool->histogram_box->view,
                                   config->low  * (n_bins - 0.0001),
                                   config->high * (n_bins - 0.0001));
}
Beispiel #8
0
static void
gimp_threshold_tool_histogram_range (GimpHistogramView *widget,
                                     gint               start,
                                     gint               end,
                                     GimpThresholdTool *t_tool)
{
    gint    n_bins = gimp_histogram_n_bins (t_tool->histogram);
    gdouble low    = (gdouble) start / (n_bins - 1);
    gdouble high   = (gdouble) end   / (n_bins - 1);

    if (low  != t_tool->config->low ||
            high != t_tool->config->high)
    {
        g_object_set (t_tool->config,
                      "low",  low,
                      "high", high,
                      NULL);
    }
}
Beispiel #9
0
static void
gimp_threshold_tool_config_notify (GimpFilterTool   *filter_tool,
                                   GimpConfig       *config,
                                   const GParamSpec *pspec)
{
  GimpThresholdTool *t_tool = GIMP_THRESHOLD_TOOL (filter_tool);

  GIMP_FILTER_TOOL_CLASS (parent_class)->config_notify (filter_tool,
                                                        config, pspec);

  if (! t_tool->histogram_box)
    return;

  if (! strcmp (pspec->name, "channel"))
    {
      GimpHistogramChannel channel;

      g_object_get (config,
                    "channel", &channel,
                    NULL);

      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 (config,
                    "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));
    }
}
Beispiel #10
0
void
gimp_levels_config_stretch_channel (GimpLevelsConfig     *config,
                                    GimpHistogram        *histogram,
                                    GimpHistogramChannel  channel)
{
  gdouble count;
  gdouble bias = 0.006;
  gint    n_bins;
  gint    i;

  g_return_if_fail (GIMP_IS_LEVELS_CONFIG (config));
  g_return_if_fail (histogram != NULL);

  g_object_freeze_notify (G_OBJECT (config));

  config->gamma[channel]       = 1.0;
  config->low_output[channel]  = 0.0;
  config->high_output[channel] = 1.0;

  n_bins = gimp_histogram_n_bins (histogram);
  count  = gimp_histogram_get_count (histogram, channel, 0, n_bins - 1);

  if (count == 0.0)
    {
      config->low_input[channel]  = 0.0;
      config->high_input[channel] = 0.0;
    }
  else
    {
      gdouble new_count;
      gdouble percentage;
      gdouble next_percentage;

      /*  Set the low input  */
      new_count = 0.0;

      for (i = 0; i < (n_bins - 1); i++)
        {
          new_count += gimp_histogram_get_value (histogram, channel, i);
          percentage = new_count / count;
          next_percentage = (new_count +
                             gimp_histogram_get_value (histogram,
                                                       channel,
                                                       i + 1)) / count;

          if (fabs (percentage - bias) < fabs (next_percentage - bias))
            {
              config->low_input[channel] = (gdouble) (i + 1) / (n_bins - 1);
              break;
            }
        }

      /*  Set the high input  */
      new_count = 0.0;

      for (i = (n_bins - 1); i > 0; i--)
        {
          new_count += gimp_histogram_get_value (histogram, channel, i);
          percentage = new_count / count;
          next_percentage = (new_count +
                             gimp_histogram_get_value (histogram,
                                                       channel,
                                                       i - 1)) / count;

          if (fabs (percentage - bias) < fabs (next_percentage - bias))
            {
              config->high_input[channel] = (gdouble) (i - 1) / (n_bins - 1);
              break;
            }
        }
    }

  g_object_notify (G_OBJECT (config), "gamma");
  g_object_notify (G_OBJECT (config), "low-input");
  g_object_notify (G_OBJECT (config), "high-input");
  g_object_notify (G_OBJECT (config), "low-output");
  g_object_notify (G_OBJECT (config), "high-output");

  g_object_thaw_notify (G_OBJECT (config));
}