static PyObject * vectors_to_selection(PyGimpVectors *self, PyObject *args, PyObject *kwargs) { GimpChannelOps operation = GIMP_CHANNEL_OP_REPLACE; gboolean antialias = TRUE, feather = FALSE; double feather_radius_x = 0.0, feather_radius_y = 0.0; static char *kwlist[] = { "operation", "antialias", "feather", "feather_radius_x", "feather_radius_y", NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiidd:to_selection", kwlist, &operation, &antialias, &feather, &feather_radius_x, &feather_radius_y)) return NULL; gimp_context_push(); gimp_context_set_antialias(antialias); gimp_context_set_feather(feather); gimp_context_set_feather_radius(feather_radius_x, feather_radius_y); gimp_image_select_item(gimp_item_get_image(self->ID), operation, self->ID); gimp_context_pop(); Py_INCREF(Py_None); return Py_None; }
/* -------------------------- * p_create_corpus_layer * -------------------------- * create the corpus layer that builds the reference pattern * for the resynthesizer call. The reference pattern is built * as duplicate of the original image reduced to the area around the current selection. * (grown by corpus_border_radius) * Note that the duplicate image has a selection, that includes the gorwn area * around the orignal selection, but EXCLUDES the original selection * (that is the area holding the object that has to be replaced * by pattern of the surrounding area) * returns the layer_id of the reference pattern. */ static gint32 p_create_corpus_layer(gint32 image_id, gint32 drawable_id, TransValues *val_ptr) { gint32 dup_image_id; gint32 channel_id; gint32 channel_2_id; GimpRGB bck_color; GimpRGB white_opaque_color; /* gboolean has_selection; */ gboolean non_empty; gint x1, y1, x2, y2; gint32 active_layer_stackposition; gint32 active_dup_layer_id; active_layer_stackposition = gap_layer_get_stackposition(image_id, drawable_id); dup_image_id = gimp_image_duplicate(image_id); channel_id = gimp_selection_save(dup_image_id); gimp_selection_grow(dup_image_id, val_ptr->corpus_border_radius); gimp_selection_invert(dup_image_id); gimp_context_get_background(&bck_color); channel_2_id = gimp_selection_save(dup_image_id); gimp_image_select_item(dup_image_id, GIMP_CHANNEL_OP_REPLACE, channel_id); gimp_rgba_set_uchar (&white_opaque_color, 255, 255, 255, 255); gimp_context_set_background(&white_opaque_color); gimp_edit_clear(channel_2_id); gimp_context_set_background(&bck_color); /* restore original background color */ gimp_selection_load(channel_2_id); gimp_selection_invert(dup_image_id); /* has_selection = */ gimp_selection_bounds(dup_image_id, &non_empty, &x1, &y1, &x2, &y2); gimp_image_crop(dup_image_id, (x2 - x1), (y2 - y1), x1, y1); gimp_selection_invert(dup_image_id); active_dup_layer_id = gap_layer_get_id_by_stackposition(dup_image_id, active_layer_stackposition); if (1==0) { /* debug code shows the duplicate image by adding a display */ gimp_display_new(dup_image_id); } return (active_dup_layer_id); } /* end p_create_corpus_layer */
static gboolean lcms_image_apply_profile (gint32 image, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, const gchar *filename, GimpColorRenderingIntent intent, gboolean bpc) { gint32 saved_selection = -1; gimp_image_undo_group_start (image); if (! lcms_image_set_profile (image, dest_profile, filename, FALSE)) { gimp_image_undo_group_end (image); return FALSE; } { gchar *src = lcms_icc_profile_get_desc (src_profile); gchar *dest = lcms_icc_profile_get_desc (dest_profile); /* ICC color profile conversion */ gimp_progress_init_printf (_("Converting from '%s' to '%s'"), src, dest); g_printerr ("lcms: converting from '%s' to '%s'\n", src, dest); g_free (dest); g_free (src); } if (! gimp_selection_is_empty (image)) { saved_selection = gimp_selection_save (image); gimp_selection_none (image); } switch (gimp_image_base_type (image)) { case GIMP_RGB: lcms_image_transform_rgb (image, src_profile, dest_profile, intent, bpc); break; case GIMP_GRAY: g_warning ("colorspace conversion not implemented for " "grayscale images"); break; case GIMP_INDEXED: lcms_image_transform_indexed (image, src_profile, dest_profile, intent, bpc); break; } if (saved_selection != -1) { gimp_image_select_item (image, GIMP_CHANNEL_OP_REPLACE, saved_selection); gimp_image_remove_channel (image, saved_selection); } gimp_progress_update (1.0); gimp_image_undo_group_end (image); return TRUE; }
static void do_zcrop (gint32 drawable_id, gint32 image_id) { GeglBuffer *drawable_buffer; GeglBuffer *shadow_buffer; gfloat *linear_buf; const Babl *format; gint x, y, width, height; gint components; gint8 *killrows; gint8 *killcols; gint32 livingrows, livingcols, destrow, destcol; gint32 selection_copy_id; gboolean has_alpha; drawable_buffer = gimp_drawable_get_buffer (drawable_id); shadow_buffer = gimp_drawable_get_shadow_buffer (drawable_id); width = gegl_buffer_get_width (drawable_buffer); height = gegl_buffer_get_height (drawable_buffer); has_alpha = gimp_drawable_has_alpha (drawable_id); if (has_alpha) format = babl_format ("R'G'B'A float"); else format = babl_format ("R'G'B' float"); components = babl_format_get_n_components (format); killrows = g_new (gint8, height); killcols = g_new (gint8, width); linear_buf = g_new (gfloat, (width > height ? width : height) * components); /* search which rows to remove */ livingrows = 0; for (y = 0; y < height; y++) { gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (0, y, width, 1), 1.0, format, linear_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); killrows[y] = TRUE; for (x = components; x < width * components; x += components) { if (! colors_equal (linear_buf, &linear_buf[x], components, has_alpha)) { livingrows++; killrows[y] = FALSE; break; } } } gimp_progress_update (0.25); /* search which columns to remove */ livingcols = 0; for (x = 0; x < width; x++) { gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (x, 0, 1, height), 1.0, format, linear_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); killcols[x] = TRUE; for (y = components; y < height * components; y += components) { if (! colors_equal (linear_buf, &linear_buf[y], components, has_alpha)) { livingcols++; killcols[x] = FALSE; break; } } } gimp_progress_update (0.5); if ((livingcols == 0 || livingrows == 0) || (livingcols == width && livingrows == height)) { g_message (_("Nothing to crop.")); g_free (linear_buf); g_free (killrows); g_free (killcols); return; } /* restitute living rows */ destrow = 0; for (y = 0; y < height; y++) { if (!killrows[y]) { gegl_buffer_copy (drawable_buffer, GEGL_RECTANGLE (0, y, width, 1), GEGL_ABYSS_NONE, shadow_buffer, GEGL_RECTANGLE (0, destrow, width, 1)); destrow++; } } gimp_progress_update (0.75); /* restitute living columns */ destcol = 0; for (x = 0; x < width; x++) { if (!killcols[x]) { gegl_buffer_copy (shadow_buffer, GEGL_RECTANGLE (x, 0, 1, height), GEGL_ABYSS_NONE, shadow_buffer, GEGL_RECTANGLE (destcol, 0, 1, height)); destcol++; } } gimp_progress_update (1.00); gimp_image_undo_group_start (image_id); selection_copy_id = gimp_selection_save (image_id); gimp_selection_none (image_id); gegl_buffer_flush (shadow_buffer); gimp_drawable_merge_shadow (drawable_id, TRUE); gegl_buffer_flush (drawable_buffer); gimp_image_select_item (image_id, GIMP_CHANNEL_OP_REPLACE, selection_copy_id); gimp_image_remove_channel (image_id, selection_copy_id); gimp_image_crop (image_id, livingcols, livingrows, 0, 0); gimp_image_undo_group_end (image_id); g_object_unref (shadow_buffer); g_object_unref (drawable_buffer); g_free (linear_buf); g_free (killrows); g_free (killcols); }
/* ------------------------------------------------------- * gap_image_set_selection_from_selection_or_drawable * ------------------------------------------------------- * create a selection in the specified image_id. * The selection is a scaled copy of the selection in another image, * referred by ref_drawable_id, or a Grayscale copy of the specified ref_drawable_id * (in case the referred image has no selection or the flag force_from_drawable is TRUE) * * - operates on a duplicate of the image referred by ref_drawable_id. * - this duplicate is scaled to same size as specified image_id * * return TRUE in case the selection was successfully created . */ gboolean gap_image_set_selection_from_selection_or_drawable(gint32 image_id, gint32 ref_drawable_id , gboolean force_from_drawable) { gint32 l_aux_channel_id; gint32 ref_image_id; gint32 work_drawable_id; /* the duplicate of the layer that is used as selction mask */ gint32 dup_image_id; gboolean has_selection; gboolean non_empty; gint x1, y1, x2, y2; if ((image_id < 0) || (ref_drawable_id < 0)) { return (FALSE); } ref_image_id = gimp_item_get_image(ref_drawable_id); if (ref_image_id < 0) { printf("ref_drawable_id does not refer to a valid image layer_id:%d\n", (int)ref_drawable_id); return (FALSE); } dup_image_id = gimp_image_duplicate(ref_image_id); if (dup_image_id < 0) { printf("duplicating of image failed, referred souce image_id:%d\n", (int)ref_image_id); return (FALSE); } /* clear undo stack */ if (gimp_image_undo_is_enabled(dup_image_id)) { gimp_image_undo_disable(dup_image_id); } if ((gimp_image_width(image_id) != gimp_image_width(dup_image_id)) || (gimp_image_height(image_id) != gimp_image_height(dup_image_id))) { if(gap_debug) { printf("scaling tmp image_id: %d\n", (int)dup_image_id); } gimp_image_scale(dup_image_id, gimp_image_width(image_id), gimp_image_height(image_id)); } has_selection = gimp_selection_bounds(ref_image_id, &non_empty, &x1, &y1, &x2, &y2); if ((has_selection) && (non_empty) && (force_from_drawable != TRUE)) { /* use scaled copy of the already exisating selection in the referred image */ work_drawable_id = gimp_image_get_selection(dup_image_id); } else { gint32 active_layer_stackposition; /* create selection as gray copy of the alt_selection layer */ active_layer_stackposition = gap_layer_get_stackposition(ref_image_id, ref_drawable_id); if(gimp_image_base_type(dup_image_id) != GIMP_GRAY) { if(gap_debug) { printf("convert to GRAYSCALE tmp image_id: %d\n", (int)dup_image_id); } gimp_image_convert_grayscale(dup_image_id); } work_drawable_id = gap_layer_get_id_by_stackposition(dup_image_id, active_layer_stackposition); gimp_layer_resize_to_image_size (work_drawable_id); } gimp_selection_all(image_id); //l_sel_channel_id = gimp_image_get_selection(image_id); l_aux_channel_id = gimp_selection_save(image_id); /* copy the work drawable (layer or channel) into the selection channel * the work layer is a grayscale copy GRAY or GRAYA of the alt_selection layer * that is already scaled and resized to fit the size of the target image * the work channel is the scaled selection of the image refred by ref_drawable_id * * copying is done into an auxiliary channel from where we regulary load the selection. * this is done because subseqent queries of the selection boudaries will deliver * full channel size rectangle after a direct copy into the selection. */ gap_layer_copy_picked_channel (l_aux_channel_id /* dst_drawable_id*/ , 0 /* dst_channel_pick */ , work_drawable_id /* src_drawable_id */ , 0 /* src_channel_pick */ , FALSE /* gboolean shadow */ ); gimp_image_select_item(image_id, GIMP_CHANNEL_OP_REPLACE, l_aux_channel_id); gimp_image_remove_channel(image_id, l_aux_channel_id); gap_image_delete_immediate(dup_image_id); return (TRUE); } /* end gap_image_set_selection_from_selection_or_drawable */