[gimp] plug-ins: wavelet-decompose improvements
- From: Thomas Manni <tmanni src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: wavelet-decompose improvements
- Date: Tue, 26 Sep 2017 11:52:05 +0000 (UTC)
commit 41a2a3634ca60f0844be64ca47aef20479b1ecec
Author: Thomas Manni <thomas manni free fr>
Date: Tue Sep 26 13:19:13 2017 +0100
plug-ins: wavelet-decompose improvements
Add an option to keep the decomposition in a layer group.
Add an option to add layer mask to each scales layers.
Do not use 'new from visible' because it produces unexpected result when
- image is already composed by several layers
- target layer has not the same size as the image canvas
Replaced by succession of layer copy and merge down.
plug-ins/common/wavelet-decompose.c | 153 +++++++++++++++++++++++++----------
1 files changed, 110 insertions(+), 43 deletions(-)
---
diff --git a/plug-ins/common/wavelet-decompose.c b/plug-ins/common/wavelet-decompose.c
index 23e2fc9..d8235e8 100644
--- a/plug-ins/common/wavelet-decompose.c
+++ b/plug-ins/common/wavelet-decompose.c
@@ -36,6 +36,8 @@
typedef struct
{
gint scales;
+ gint create_group;
+ gint create_masks;
} WaveletDecomposeParams;
@@ -50,13 +52,17 @@ static void run (const gchar *name,
static void wavelet_blur (gint32 drawable_id,
gint radius);
+
+
static gboolean wavelet_decompose_dialog (void);
/* create a few globals, set default values */
static WaveletDecomposeParams wavelet_params =
{
- 5 /* default scales */
+ 5, /* default scales */
+ 1, /* create group */
+ 0 /* do not add mask by default */
};
const GimpPlugInInfo PLUG_IN_INFO =
@@ -76,10 +82,15 @@ query (void)
{
static const GimpParamDef args[] =
{
- { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
- { GIMP_PDB_IMAGE, "image", "Input image (unused)" },
- { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
- { GIMP_PDB_INT32, "scales", "Number of scales (1-7)" }
+ { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), "
+ "RUN-NONINTERACTIVE (1) }" },
+ { GIMP_PDB_IMAGE, "image", "Input image (unused)" },
+ { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
+ { GIMP_PDB_INT32, "scales", "Number of scales (1-7)" },
+ { GIMP_PDB_INT32, "create-group", "Create a layer group to store the "
+ "decomposition" },
+ { GIMP_PDB_INT32, "create-masks", "Add a layer mask to each scales "
+ "layers" }
};
gimp_install_procedure (PLUG_IN_PROC,
@@ -134,13 +145,15 @@ run (const gchar *name,
break;
case GIMP_RUN_NONINTERACTIVE:
- if (nparams != 4)
+ if (nparams != 6)
{
status = GIMP_PDB_CALLING_ERROR;
}
else
{
- wavelet_params.scales = param[3].data.d_int32;
+ wavelet_params.scales = param[3].data.d_int32;
+ wavelet_params.create_group = param[4].data.d_int32;
+ wavelet_params.create_masks = param[5].data.d_int32;
}
break;
@@ -155,58 +168,89 @@ run (const gchar *name,
if (status == GIMP_PDB_SUCCESS)
{
gint32 *scale_ids;
- gint32 original_id;
+ gint32 new_scale_id;
+ gint32 parent_id;
gint id;
gimp_progress_init (_("Wavelet-Decompose"));
gimp_image_undo_group_start (image_id);
+ if (wavelet_params.create_group)
+ {
+ gint32 group_id = gimp_layer_group_new (image_id);
+ gimp_item_set_name (group_id, _("Decomposition"));
+ gimp_item_set_visible (group_id, FALSE);
+ gimp_image_insert_layer (image_id, group_id,
+ gimp_item_get_parent (drawable_id),
+ gimp_image_get_item_position (image_id,
+ drawable_id));
+ parent_id = group_id;
+ }
+ else
+ parent_id = -1;
+
scale_ids = g_new (gint32, wavelet_params.scales);
- original_id = gimp_layer_copy (drawable_id);
- gimp_image_insert_layer (image_id, original_id, -1, 0);
+ new_scale_id = gimp_layer_copy (drawable_id);
+ gimp_image_insert_layer (image_id, new_scale_id, parent_id,
+ gimp_image_get_item_position (image_id,
+ drawable_id));
for (id = 0 ; id < wavelet_params.scales; ++id)
{
- gint32 blur_id;
+ gint32 blur_id, tmp_id;
gchar scale_name[20];
gimp_progress_update ((gdouble) id / (gdouble) wavelet_params.scales);
- /* blur */
- blur_id = gimp_layer_copy (original_id);
- gimp_image_insert_layer (image_id, blur_id, 0,
- gimp_image_get_item_position (image_id,
- original_id));
- wavelet_blur (blur_id, 1 << id);
+ scale_ids[id] = new_scale_id;
- /* grain extract */
- gimp_layer_set_mode (blur_id, GIMP_LAYER_MODE_GRAIN_EXTRACT);
-
- /* new from visible */
g_snprintf (scale_name, sizeof (scale_name), "Scale %d", id + 1);
- scale_ids[id] = gimp_layer_new_from_visible (image_id, image_id,
- scale_name);
+ gimp_item_set_name (new_scale_id, scale_name);
- gimp_image_insert_layer (image_id, scale_ids[id], 0,
+ tmp_id = gimp_layer_copy (new_scale_id);
+ gimp_image_insert_layer (image_id, tmp_id, parent_id,
gimp_image_get_item_position (image_id,
- blur_id));
- gimp_layer_set_mode (scale_ids[id], GIMP_LAYER_MODE_GRAIN_MERGE);
- gimp_layer_set_mode (blur_id, GIMP_LAYER_MODE_NORMAL);
- gimp_item_set_visible (scale_ids[id], FALSE);
+ new_scale_id));
+ wavelet_blur (tmp_id, pow(2.0, id));
+
+ blur_id = gimp_layer_copy (tmp_id);
+ gimp_image_insert_layer (image_id, blur_id, parent_id,
+ gimp_image_get_item_position (image_id,
+ tmp_id));
- gimp_image_remove_layer (image_id, original_id);
+ gimp_layer_set_mode (tmp_id, GIMP_LAYER_MODE_GRAIN_EXTRACT);
+ new_scale_id = gimp_image_merge_down (image_id, tmp_id,
+ GIMP_EXPAND_AS_NECESSARY);
+ scale_ids[id] = new_scale_id;
- original_id = blur_id;
+ gimp_item_set_visible (new_scale_id, FALSE);
+
+ new_scale_id = blur_id;
}
- gimp_item_set_name (original_id, "Residual");
+ gimp_item_set_name (new_scale_id, "residual");
- for (id = 0 ; id < wavelet_params.scales; ++id)
+ for (id = 0; id < wavelet_params.scales; id++)
{
+ gimp_image_reorder_item (image_id, scale_ids[id], parent_id,
+ gimp_image_get_item_position (image_id,
+ new_scale_id));
+ gimp_layer_set_mode (scale_ids[id], GIMP_LAYER_MODE_GRAIN_MERGE);
+
+ if (wavelet_params.create_masks)
+ {
+ gint32 mask_id = gimp_layer_create_mask (scale_ids[id],
+ GIMP_ADD_MASK_WHITE);
+ gimp_layer_add_mask (scale_ids[id], mask_id);
+ }
+
gimp_item_set_visible (scale_ids[id], TRUE);
}
+ if (wavelet_params.create_group)
+ gimp_item_set_visible (parent_id, TRUE);
+
g_free (scale_ids);
gimp_image_undo_group_end (image_id);
@@ -233,23 +277,19 @@ wavelet_blur (gint32 drawable_id,
if (gimp_drawable_mask_intersect (drawable_id, &x, &y, &width, &height))
{
- GeglBuffer *buffer;
- GeglBuffer *shadow_buffer;
-
- buffer = gimp_drawable_get_buffer (drawable_id);
- shadow_buffer = gimp_drawable_get_shadow_buffer (drawable_id);
+ GeglBuffer *buffer = gimp_drawable_get_buffer (drawable_id);
+ GeglBuffer *shadow = gimp_drawable_get_shadow_buffer (drawable_id);
- gegl_render_op (buffer, shadow_buffer,
+ gegl_render_op (buffer, shadow,
"gegl:wavelet-blur",
"radius", (gdouble) radius,
NULL);
- g_object_unref (shadow_buffer); /* flushes the shadow blur */
- g_object_unref (buffer);
-
- gimp_drawable_merge_shadow (drawable_id, TRUE);
+ gegl_buffer_flush (shadow);
+ gimp_drawable_merge_shadow (drawable_id, FALSE);
gimp_drawable_update (drawable_id, x, y, width, height);
- gimp_displays_flush ();
+ g_object_unref (buffer);
+ g_object_unref (shadow);
}
}
@@ -259,6 +299,7 @@ wavelet_decompose_dialog (void)
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *table;
+ GtkWidget *button;
GtkObject *adj;
gboolean run;
@@ -292,6 +333,8 @@ wavelet_decompose_dialog (void)
gtk_box_pack_start (GTK_BOX (main_vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
+ /* scales */
+
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
_("Scales:"), SCALE_WIDTH, ENTRY_WIDTH,
wavelet_params.scales,
@@ -303,6 +346,30 @@ wavelet_decompose_dialog (void)
G_CALLBACK (gimp_int_adjustment_update),
&wavelet_params.scales);
+ /* create group layer */
+
+ button = gtk_check_button_new_with_mnemonic (_("Create a layer group to store the decomposition"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+ wavelet_params.create_group);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "toggled",
+ G_CALLBACK (gimp_toggle_button_update),
+ &wavelet_params.create_group);
+
+ /* create layer masks */
+
+ button = gtk_check_button_new_with_mnemonic (_("Add a layer mask to each scales layers"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+ wavelet_params.create_masks);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "toggled",
+ G_CALLBACK (gimp_toggle_button_update),
+ &wavelet_params.create_masks);
+
gtk_widget_show (dialog);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]