示例#1
0
GimpLayer *
gimp_image_merge_group_layer (GimpImage      *image,
                              GimpGroupLayer *group)
{
  GimpLayer *parent;
  GimpLayer *layer;
  gint       index;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (GIMP_IS_GROUP_LAYER (group), NULL);
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (group)), NULL);
  g_return_val_if_fail (gimp_item_get_image (GIMP_ITEM (group)) == image, NULL);

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE,
                               C_("undo-type", "Merge Layer Group"));

  parent = gimp_layer_get_parent (GIMP_LAYER (group));
  index  = gimp_item_get_index (GIMP_ITEM (group));

  layer = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (group),
                                           GIMP_TYPE_LAYER));

  gimp_object_set_name (GIMP_OBJECT (layer), gimp_object_get_name (group));

  gimp_image_remove_layer (image, GIMP_LAYER (group), TRUE, NULL);
  gimp_image_add_layer (image, layer, parent, index, TRUE);

  gimp_image_undo_group_end (image);

  return layer;
}
示例#2
0
void
gimp_create_image_from_buffer (Gimp       *gimp,
                               GeglBuffer *buffer)
{
  GimpImage  *image;
  GimpLayer  *layer;
  const Babl *format;

  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (GEGL_IS_BUFFER (buffer));

  format = gegl_buffer_get_format (buffer);

  image = gimp_create_image (gimp,
                             gegl_buffer_get_width  (buffer),
                             gegl_buffer_get_height (buffer),
                             gimp_babl_format_get_base_type (format),
                             gimp_babl_format_get_precision (format),
                             FALSE);

  layer = gimp_layer_new_from_buffer (buffer, image, format,
                                      "Debug Image",
                                      GIMP_OPACITY_OPAQUE,
                                      GIMP_NORMAL_MODE);
  gimp_image_add_layer (image, layer, NULL, -1, FALSE);

  gimp_create_display (gimp, image, GIMP_UNIT_PIXEL, 1.0);
}
示例#3
0
void
edit_paste_as_new_layer_cmd_callback (GtkAction *action,
                                      gpointer   data)
{
  Gimp       *gimp;
  GimpImage  *image;
  GimpBuffer *buffer;
  return_if_no_gimp (gimp, data);
  return_if_no_image (image, data);

  buffer = gimp_clipboard_get_buffer (gimp);

  if (buffer)
    {
      GimpLayer *layer;

      layer = gimp_layer_new_from_buffer (gimp_buffer_get_buffer (buffer),
                                          image,
                                          gimp_image_get_layer_format (image,
                                                                       TRUE),
                                          _("Clipboard"),
                                          GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
      g_object_unref (buffer);

      gimp_image_add_layer (image, layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_flush (image);
    }
  else
    {
      gimp_message_literal (gimp, NULL, GIMP_MESSAGE_WARNING,
			    _("There is no image data in the clipboard to paste."));
    }
}
示例#4
0
文件: screenshot.c 项目: Minoos/gimp
static gint32
create_image (GdkPixbuf   *pixbuf,
              GdkRegion   *shape,
              const gchar *name)
{
  gint32     image;
  gint32     layer;
  gdouble    xres, yres;
  gchar     *comment;
  gint       width, height;
  gboolean   status;

  status = gimp_progress_init (_("Importing screenshot"));

  width  = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_undo_disable (image);

  gimp_get_monitor_resolution (&xres, &yres);
  gimp_image_set_resolution (image, xres, yres);

  comment = gimp_get_default_comment ();
  if (comment)
    {
      GimpParasite *parasite;

      parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT,
                                    strlen (comment) + 1, comment);

      gimp_image_parasite_attach (image, parasite);
      gimp_parasite_free (parasite);

      g_free (comment);
    }

  layer = gimp_layer_new_from_pixbuf (image,
                                      name ? name : _("Screenshot"),
                                      pixbuf,
                                      100, GIMP_NORMAL_MODE, 0.0, 1.0);
  gimp_image_add_layer (image, layer, 0);

  if (shape && ! gdk_region_empty (shape))
    {
      image_select_shape (image, shape);

      if (! gimp_selection_is_empty (image))
        {
          gimp_layer_add_alpha (layer);
          gimp_edit_clear (layer);
          gimp_selection_none (image);
        }
    }

  gimp_image_undo_enable (image);

  return image;
}
示例#5
0
static void
gimp_display_shell_drop_component (GtkWidget       *widget,
                                   gint             x,
                                   gint             y,
                                   GimpImage       *image,
                                   GimpChannelType  component,
                                   gpointer         data)
{
  GimpDisplayShell *shell      = GIMP_DISPLAY_SHELL (data);
  GimpImage        *dest_image = gimp_display_get_image (shell->display);
  GimpChannel      *channel;
  GimpItem         *new_item;
  const gchar      *desc;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! dest_image)
    {
      dest_image = gimp_image_new_from_component (image->gimp,
                                                  image, component);
      gimp_create_display (dest_image->gimp, dest_image, GIMP_UNIT_PIXEL, 1.0,
                           G_OBJECT (gtk_widget_get_screen (widget)),
                           gimp_widget_get_monitor (widget));
      g_object_unref (dest_image);

      return;
    }

  channel = gimp_channel_new_from_component (image, component, NULL, NULL);

  new_item = gimp_item_convert (GIMP_ITEM (channel),
                                dest_image, GIMP_TYPE_LAYER);
  g_object_unref (channel);

  if (new_item)
    {
      GimpLayer *new_layer = GIMP_LAYER (new_item);

      gimp_enum_get_value (GIMP_TYPE_CHANNEL_TYPE, component,
                           NULL, NULL, &desc, NULL);
      gimp_object_take_name (GIMP_OBJECT (new_layer),
                             g_strdup_printf (_("%s Channel Copy"), desc));

      gimp_image_undo_group_start (dest_image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      gimp_display_shell_dnd_position_item (shell, image, new_item);

      gimp_image_add_layer (dest_image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_undo_group_end (dest_image);

      gimp_display_shell_dnd_flush (shell, dest_image);
    }
}
示例#6
0
static void
gimp_display_shell_drop_pixbuf (GtkWidget *widget,
                                gint       x,
                                gint       y,
                                GdkPixbuf *pixbuf,
                                gpointer   data)
{
  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image = gimp_display_get_image (shell->display);
  GimpLayer        *new_layer;
  gboolean          has_alpha = FALSE;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! image)
    {
      image = gimp_image_new_from_pixbuf (shell->display->gimp, pixbuf,
                                          _("Dropped Buffer"));
      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0,
                           G_OBJECT (gtk_widget_get_screen (widget)),
                           gimp_widget_get_monitor (widget));
      g_object_unref (image);

      return;
    }

  if (gdk_pixbuf_get_n_channels (pixbuf) == 2 ||
      gdk_pixbuf_get_n_channels (pixbuf) == 4)
    {
      has_alpha = TRUE;
    }

  new_layer =
    gimp_layer_new_from_pixbuf (pixbuf, image,
                                gimp_image_get_layer_format (image, has_alpha),
                                _("Dropped Buffer"),
                                GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

  if (new_layer)
    {
      GimpItem *new_item = GIMP_ITEM (new_layer);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      gimp_display_shell_dnd_position_item (shell, image, new_item);

      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }
}
示例#7
0
static void
gimp_display_shell_drop_drawable (GtkWidget    *widget,
                                  gint          x,
                                  gint          y,
                                  GimpViewable *viewable,
                                  gpointer      data)
{
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image     = gimp_display_get_image (shell->display);
  GType             new_type;
  GimpItem         *new_item;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! image)
    {
      image = gimp_image_new_from_drawable (shell->display->gimp,
                                            GIMP_DRAWABLE (viewable));
      gimp_create_display (shell->display->gimp, image, GIMP_UNIT_PIXEL, 1.0,
                           G_OBJECT (gtk_widget_get_screen (widget)),
                           gimp_widget_get_monitor (widget));
      g_object_unref (image);

      return;
    }

  if (GIMP_IS_LAYER (viewable))
    new_type = G_TYPE_FROM_INSTANCE (viewable);
  else
    new_type = GIMP_TYPE_LAYER;

  new_item = gimp_item_convert (GIMP_ITEM (viewable), image, new_type);

  if (new_item)
    {
      GimpLayer *new_layer = GIMP_LAYER (new_item);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      gimp_display_shell_dnd_position_item (shell, image, new_item);

      gimp_item_set_visible (new_item, TRUE, FALSE);
      gimp_item_set_linked (new_item, FALSE, FALSE);

      gimp_image_add_layer (image, new_layer,
                            GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }
}
示例#8
0
static gboolean
debug_show_image_graph (GimpImage *source_image)
{
  Gimp            *gimp        = source_image->gimp;
  GimpProjectable *projectable = GIMP_PROJECTABLE (source_image);
  GeglNode        *image_graph = gimp_projectable_get_graph (projectable);
  GeglNode        *output_node = gegl_node_get_output_proxy (image_graph, "output");
  GimpImage       *new_image   = NULL;
  GimpLayer       *layer       = NULL;
  GeglNode        *introspect  = NULL;
  GeglNode        *sink        = NULL;
  GeglBuffer      *buffer      = NULL;
  gchar           *new_name    = NULL;

  /* Setup and process the introspection graph */
  introspect = gegl_node_new_child (NULL,
                                    "operation", "gegl:introspect",
                                    "node",      output_node,
                                    NULL);
  sink = gegl_node_new_child (NULL,
                              "operation", "gegl:buffer-sink",
                              "buffer",    &buffer,
                              NULL);
  gegl_node_link_many (introspect, sink, NULL);
  gegl_node_process (sink);

  /* Create a new image of the result */
  new_name = g_strdup_printf ("%s GEGL graph",
                              gimp_image_get_display_name (source_image));
  new_image = gimp_create_image (gimp,
                                 gegl_buffer_get_width (buffer),
                                 gegl_buffer_get_height (buffer),
                                 GIMP_RGB,
                                 GIMP_PRECISION_U8,
                                 FALSE);
  gimp_image_set_uri (new_image, new_name);
  layer = gimp_layer_new_from_buffer (buffer,
                                      new_image,
                                      gimp_image_get_layer_format (new_image,
                                                                   TRUE),
                                      new_name,
                                      1.0,
                                      GIMP_NORMAL_MODE);
  gimp_image_add_layer (new_image, layer, NULL, 0, FALSE);
  gimp_create_display (gimp, new_image, GIMP_UNIT_PIXEL, 1.0);

  /* Cleanup */
  g_object_unref (new_image);
  g_free (new_name);
  g_object_unref (buffer);
  g_object_unref (sink);
  g_object_unref (introspect);
  g_object_unref (source_image);

  return FALSE;
}
示例#9
0
文件: dog.c 项目: Amerekanets/gimp
static void
preview_update_preview (GimpPreview  *preview,
                        GimpDrawable *drawable)
{
  gint          x1, y1;
  gint          width, height;
  gint          bpp;
  guchar       *buffer;
  GimpPixelRgn  src_rgn;
  GimpPixelRgn  preview_rgn;
  gint32        image_id, src_image_id;
  gint32        preview_id;
  GimpDrawable *preview_drawable;

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  gimp_preview_get_position (preview, &x1, &y1);
  gimp_preview_get_size (preview, &width, &height);

  buffer = g_new (guchar, width * height * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_get_rect (&src_rgn, buffer,
                           x1, y1, width, height);

  /* set up gimp drawable for rendering preview into */
  src_image_id = gimp_drawable_get_image (drawable->drawable_id);
  image_id = gimp_image_new (width, height,
                             gimp_image_base_type (src_image_id));
  preview_id = gimp_layer_new (image_id, "preview", width, height,
                               gimp_drawable_type (drawable->drawable_id),
                               100,
                               GIMP_NORMAL_MODE);
  preview_drawable = gimp_drawable_get (preview_id);
  gimp_image_add_layer (image_id, preview_id, 0);
  gimp_layer_set_offsets (preview_id, 0, 0);
  gimp_pixel_rgn_init (&preview_rgn, preview_drawable,
                       0, 0, width, height, TRUE, TRUE);
  gimp_pixel_rgn_set_rect (&preview_rgn, buffer,
                           0, 0, width, height);
  gimp_drawable_flush (preview_drawable);
  gimp_drawable_merge_shadow (preview_id, TRUE);
  gimp_drawable_update (preview_id, 0, 0, width, height);

  dog (image_id, preview_drawable, dogvals.inner, dogvals.outer, FALSE);

  gimp_pixel_rgn_get_rect (&preview_rgn, buffer,
                           0, 0, width, height);

  gimp_preview_draw_buffer (preview, buffer, width * bpp);

  gimp_image_delete (image_id);
  g_free (buffer);
}
示例#10
0
/* -----------------------
 * p_tri_map_preprocessing
 * -----------------------
 * prepare the tri mask for processing
 * - have bpp == 1
 * - have same size and offset as the input drawable (that is a layer)
 * - pixel values >= 240 are set to value 240 (MATTING_USER_FOREGROUND)
 * - in case the input layer already has an alpha channel
 *   all fully transparent (alpha == 0) pixels are also set 0 (MATTING_USER_BACKGROUND)
 *   in the tri map to keep pixels fully transparent. (such pixels typicall do not
 *   have a useful color information in the RGB channels)
 *
 *
 * in case the user provided the tri map as layer or channel that is NOT the layermask of the input layer
 * we create a new dummy layer with same size and offset as the input layer
 * and add a layermask to this dummy layer.
 * The layermask of the dummy layer is then filled with the intersecting grayscale copy
 * of the user-provided triMap drawable and will be used as tri map in the alpha matting processing.
 *
 * returns the dawable Id of the relevant TRI MAP that fulfills the conditons listed above.
 */
static gint32
p_tri_map_preprocessing (GimpDrawable *drawable, GapFgExtractValues *fgValPtr, gint32 *dummyLayerId)
{
  gint32           prepocessedTriMapLayerId;
  gint32           inputLayerMaskId;
  gint32           imageId;

  *dummyLayerId = -1;
  imageId = gimp_drawable_get_image(drawable->drawable_id);


  inputLayerMaskId = gimp_layer_get_mask(drawable->drawable_id);
  if (fgValPtr->tri_map_drawable_id == inputLayerMaskId)
  {
    prepocessedTriMapLayerId = inputLayerMaskId;
  }
  else
  {
    gint          offset_x;
    gint          offset_y;
    gint32        dummyLayerMaskId;
    gint32        l_fsel_layer_id;

    *dummyLayerId = gimp_layer_new(imageId
            , "DUMMY"
            , drawable->width
            , drawable->height
            , GIMP_RGBA_IMAGE
            , 100.0   /* full opacity */
            , GIMP_NORMAL_MODE       /* normal mode */
            );

    /* get offsets of the input drawable (layer) within the image */
    gimp_drawable_offsets (drawable->drawable_id, &offset_x, &offset_y);

    /* add dummy layer (of same size at same offsets) to the same image */
    gimp_image_add_layer(imageId, *dummyLayerId, -1 /* stackposition */ );
    gimp_layer_set_offsets(*dummyLayerId, offset_x, offset_y);

    /* create a new layermask (black is full transparent */
    dummyLayerMaskId = gimp_layer_create_mask(*dummyLayerId, GIMP_ADD_BLACK_MASK);
    gimp_layer_add_mask(*dummyLayerId, dummyLayerMaskId);

    gimp_edit_copy(fgValPtr->tri_map_drawable_id);
    l_fsel_layer_id = gimp_edit_paste(dummyLayerMaskId, FALSE);
    gimp_floating_sel_anchor(l_fsel_layer_id);

    prepocessedTriMapLayerId = dummyLayerMaskId;
  }

  gap_fg_rgn_tri_map_normalize(drawable, prepocessedTriMapLayerId);

  return(prepocessedTriMapLayerId);

}       /* end p_tri_map_preprocessing */
示例#11
0
void
floating_sel_attach (GimpLayer    *layer,
                     GimpDrawable *drawable)
{
  GimpImage *image;
  GimpLayer *floating_sel;

  g_return_if_fail (GIMP_IS_LAYER (layer));
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (drawable != GIMP_DRAWABLE (layer));
  g_return_if_fail (gimp_item_get_image (GIMP_ITEM (layer)) ==
                    gimp_item_get_image (GIMP_ITEM (drawable)));

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  floating_sel = gimp_image_floating_sel (image);

  /*  If there is already a floating selection, anchor it  */
  if (floating_sel)
    {
      floating_sel_anchor (floating_sel);

      /*  if we were pasting to the old floating selection, paste now
       *  to the drawable
       */
      if (drawable == (GimpDrawable *) floating_sel)
        drawable = gimp_image_get_active_drawable (image);
    }

  /*  set the drawable and allocate a backing store  */
  gimp_layer_set_lock_alpha (layer, TRUE, FALSE);
  layer->fs.drawable      = drawable;
  layer->fs.backing_store = tile_manager_new (GIMP_ITEM (layer)->width,
                                              GIMP_ITEM (layer)->height,
                                              gimp_drawable_bytes (drawable));

  /*  add the layer to the image  */
  gimp_image_add_layer (image, layer, 0);

  /*  store the affected area from the drawable in the backing store  */
  floating_sel_rigor (layer, TRUE);
}
示例#12
0
void
callback_new_mask_button (GtkWidget * button, gpointer data)
{
  gint32 layer_ID;
  NewLayerData *nl_data = NEW_LAYER_DATA (data);
  PreviewData *p_data = nl_data->preview_data;
  GimpImageType image_type;

  IMAGE_CHECK_ACTION(p_data->image_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_FATAL), );

  switch (gimp_image_base_type (p_data->image_ID))
    {
      case GIMP_RGB:
        image_type = GIMP_RGBA_IMAGE;
        break;
      case GIMP_GRAY:
        image_type = GIMP_GRAYA_IMAGE;
        break;
      default:
        return;
    }

  gimp_image_undo_group_start (p_data->image_ID);
  layer_ID =
    gimp_layer_new (p_data->image_ID, nl_data->name,
		    p_data->old_width, p_data->old_height,
		    image_type, 50, GIMP_NORMAL_MODE);
  gimp_image_add_layer (p_data->image_ID, layer_ID, -1);
  gimp_drawable_fill (layer_ID, GIMP_TRANSPARENT_FILL);
  gimp_layer_translate (layer_ID, p_data->x_off, p_data->y_off);
  gimp_image_undo_group_end (p_data->image_ID);
  *(nl_data->layer_ID) = layer_ID;
  *(nl_data->status) = TRUE;

  nl_data->preview_data->ui_vals->layer_on_edit_ID = layer_ID;
  nl_data->preview_data->ui_vals->layer_on_edit_type = nl_data->layer_type;
  nl_data->preview_data->ui_vals->layer_on_edit_is_new = TRUE;

  g_free(nl_data);

  gtk_dialog_response (GTK_DIALOG(dlg), RESPONSE_WORK_ON_AUX_LAYER);
}
static gint32 create_new_layer(
    gint32              img,
    gint                position,
    const gchar*        layername,
    guint               width,
    guint               height,
    GimpImageBaseType   bas_type,
    GimpDrawable**      drawable,
    GimpPixelRgn*       pixel_rgn)
{
    gint32        layer;
    GimpImageType img_type = GIMP_RGB_IMAGE;

    /* TODO: add support for GIMP_RGBA_IMAGE in case of RGBA888 */
    switch (bas_type)
    {
	case GIMP_RGB:
	    img_type = GIMP_RGB_IMAGE;
	    break;
	case GIMP_GRAY:
	    img_type = GIMP_GRAY_IMAGE;
	    break;
	case GIMP_INDEXED:
	    img_type = GIMP_INDEXED_IMAGE;
	    break;
    }

    if (!layername) {
	layername = "background";
    }

    layer = gimp_layer_new(img, layername, width, height, img_type, 100,
							    GIMP_NORMAL_MODE);
    gimp_image_add_layer(img, layer, position);

    *drawable = gimp_drawable_get(layer);
    gimp_pixel_rgn_init(pixel_rgn, *drawable, 0, 0, (*drawable)->width,
					    (*drawable)->height, TRUE, FALSE);

    return layer;
}
示例#14
0
文件: svg.c 项目: Minoos/gimp
static gint32
load_image (const gchar *filename)
{
  gint32        image;
  gint32        layer;
  GdkPixbuf    *pixbuf;
  gint          width;
  gint          height;
  GError       *error = NULL;

  pixbuf = load_rsvg_pixbuf (filename, &load_vals, &error);

  if (!pixbuf)
    {
      /*  Do not rely on librsvg setting GError on failure!  */
      g_message (_("Could not open '%s' for reading: %s"),
                 gimp_filename_to_utf8 (filename),
                 error ? error->message : _("Unknown reason"));
      return -1;
    }

  gimp_progress_init (_("Rendering SVG"));

  width  = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_undo_disable (image);

  gimp_image_set_filename (image, filename);
  gimp_image_set_resolution (image,
                             load_vals.resolution, load_vals.resolution);

  layer = gimp_layer_new_from_pixbuf (image, _("Rendered SVG"), pixbuf,
                                      100, GIMP_NORMAL_MODE, 0.0, 1.0);
  gimp_image_add_layer (image, layer, 0);

  gimp_image_undo_enable (image);

  return image;
}
示例#15
0
/* ----------------------------------------
 * p_createEmptyEdgeDrawable
 * ----------------------------------------
 * create the (empty) edge drawable as layer of a new image
 *
 */
static void
p_createEmptyEdgeDrawable(GapEdgeContext *ectx)
{
  ectx->edgeImageId = gimp_image_new(ectx->refDrawable->width
                                   , ectx->refDrawable->height
                                   , GIMP_GRAY
                                   );
  ectx->edgeDrawableId = gimp_layer_new(ectx->edgeImageId
                , "edge"
                , ectx->refDrawable->width
                , ectx->refDrawable->height
                , GIMP_GRAY_IMAGE
                , 100.0   /* full opacity */
                , 0       /* normal mode */
                );

  gimp_image_add_layer (ectx->edgeImageId, ectx->edgeDrawableId, 0 /* stackposition */ );

  ectx->edgeDrawable = gimp_drawable_get(ectx->edgeDrawableId);
  
}  /* end p_createEmptyEdgeDrawable */
示例#16
0
static gint32
create_new_layer (gint32              image_ID,
                  gint                position,
                  const gchar        *layername,
                  guint               width,
                  guint               height,
                  GimpImageBaseType   type,
                  GimpDrawable      **drawable,
                  GimpPixelRgn       *pixel_rgn)
{
  gint32        layer_ID;
  GimpImageType gdtype = GIMP_RGB_IMAGE;

  switch (type)
    {
    case GIMP_RGB:
      gdtype = GIMP_RGB_IMAGE;
      break;
    case GIMP_GRAY:
      gdtype = GIMP_GRAY_IMAGE;
      break;
    case GIMP_INDEXED:
      gdtype = GIMP_INDEXED_IMAGE;
      break;
    }

  if (!layername)
    layername = _("Background");

  layer_ID = gimp_layer_new (image_ID, layername, width, height,
                             gdtype, 100, GIMP_NORMAL_MODE);
  gimp_image_add_layer (image_ID, layer_ID, position);

  *drawable = gimp_drawable_get (layer_ID);
  gimp_pixel_rgn_init (pixel_rgn, *drawable, 0, 0, (*drawable)->width,
		       (*drawable)->height, TRUE, FALSE);

  return layer_ID;
}
示例#17
0
static GimpLayer *
gimp_image_duplicate_layers (GimpImage *image,
                             GimpImage *new_image)
{
  GimpLayer *active_layer = NULL;
  GList     *list;
  gint       count;

  for (list = gimp_image_get_layer_iter (image), count = 0;
       list;
       list = g_list_next (list))
    {
      GimpLayer *layer = list->data;
      GimpLayer *new_layer;

      if (gimp_layer_is_floating_sel (layer))
        continue;

      new_layer = GIMP_LAYER (gimp_image_duplicate_item (GIMP_ITEM (layer),
                                                         new_image));

      /*  Make sure that if the layer has a layer mask,
       *  its name isn't screwed up
       */
      if (new_layer->mask)
        gimp_object_set_name (GIMP_OBJECT (new_layer->mask),
                              gimp_object_get_name (layer->mask));

      if (gimp_image_get_active_layer (image) == layer)
        active_layer = new_layer;

      gimp_image_add_layer (new_image, new_layer,
                            NULL, count++, FALSE);
    }

  return active_layer;
}
void
floating_sel_attach (GimpLayer    *layer,
                     GimpDrawable *drawable)
{
  GimpImage *image;
  GimpLayer *floating_sel;

  g_return_if_fail (GIMP_IS_LAYER (layer));
  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
  g_return_if_fail (drawable != GIMP_DRAWABLE (layer));
  g_return_if_fail (gimp_item_get_image (GIMP_ITEM (layer)) ==
                    gimp_item_get_image (GIMP_ITEM (drawable)));

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  floating_sel = gimp_image_get_floating_selection (image);

  /*  If there is already a floating selection, anchor it  */
  if (floating_sel)
    {
      floating_sel_anchor (floating_sel);

      /*  if we were pasting to the old floating selection, paste now
       *  to the drawable
       */
      if (drawable == (GimpDrawable *) floating_sel)
        drawable = gimp_image_get_active_drawable (image);
    }

  gimp_layer_set_lock_alpha (layer, TRUE, FALSE);

  gimp_layer_set_floating_sel_drawable (layer, drawable);

  gimp_image_add_layer (image, layer, NULL, 0, TRUE);
}
static void preview_ambient_occlusion_only(gint32 image_ID) {
    gint32 drawable_ID = -1;
    gint32 drawableAO_ID = -1;
    
    gtk_label_set_text(GTK_LABEL(progress_label), "Mixing Colors");
    // preview_diffuse_only(image_ID);
    preview_normal_only(image_ID);
    // if (preview_normal_only(image_ID) != NULL) return NULL;
    drawable_ID = gimp_image_get_active_layer(image_ID);
    /** Copy active layer. */
    /** LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL */
    drawableAO_ID = gimp_layer_copy (drawable_ID);
    /** Add new layer to image. */
    gimp_image_add_layer(image_ID, drawableAO_ID, -1);
    /** Set new layer as active. */
    gimp_image_set_active_layer(image_ID, drawableAO_ID);

    /**
     * Colors ->  Components -> "Channel Mixer" applied
     * Standard plug-in. Source code ships with GIMP.
     * 
     * Add the "f" here to signify float in c language.
     * Removed 0.0 on first param and changed to 0 because boolean.
     */
    
    /** Explained on line ~1300 of InsaneBump.c */
    // if (plug_in_colors_channel_mixer_connector(image_ID, drawableAO_ID, 0, -200.0f, 0.0f, 0.0f, 0.0f, -200.0f, 0.0f, 0.0f, 0.0f, 1.0f) != 1) return;
    if (plug_in_colors_channel_mixer_connector(image_ID, drawableAO_ID, 0, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f) != 1) return;
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), 0.87);
    
    gimp_desaturate(drawableAO_ID);
    gimp_levels_stretch(drawableAO_ID);
    
    pDrawables.drawable_ao = gimp_drawable_get(drawableAO_ID);
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress), 0.90);
}
示例#20
0
GimpLayer *
text_render (GimpImage    *image,
             GimpDrawable *drawable,
             GimpContext  *context,
             gint          text_x,
             gint          text_y,
             const gchar  *fontname,
             const gchar  *text,
             gint          border,
             gboolean      antialias)
{
  PangoFontDescription *desc;
  GimpText             *gtext;
  GimpLayer            *layer;
  GimpRGB               color;
  gchar                *font;
  gdouble               size;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (drawable == NULL ||
                        gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (fontname != NULL, NULL);
  g_return_val_if_fail (text != NULL, NULL);

  if (border < 0)
    border = 0;

  desc = pango_font_description_from_string (fontname);
  size = PANGO_PIXELS (pango_font_description_get_size (desc));

  pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
  font = pango_font_description_to_string (desc);

  pango_font_description_free (desc);

  gimp_context_get_foreground (context, &color);

  gtext = g_object_new (GIMP_TYPE_TEXT,
                        "text",      text,
                        "font",      font,
                        "font-size", size,
                        "antialias", antialias,
                        "border",    border,
                        "color",     &color,
                        NULL);

  g_free (font);

  layer = gimp_text_layer_new (image, gtext);

  g_object_unref (gtext);

  if (!layer)
    return NULL;

  /*  Start a group undo  */
  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT,
                               _("Add Text Layer"));

  /*  Set the layer offsets  */
  gimp_item_set_offset (GIMP_ITEM (layer), text_x, text_y);

  /*  If there is a selection mask clear it--
   *  this might not always be desired, but in general,
   *  it seems like the correct behavior.
   */
  if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
    gimp_channel_clear (gimp_image_get_mask (image), NULL, TRUE);

  if (drawable == NULL)
    {
      /*  If the drawable is NULL, create a new layer  */
      gimp_image_add_layer (image, layer, NULL, -1, TRUE);
    }
  else
    {
      /*  Otherwise, instantiate the text as the new floating selection */
      floating_sel_attach (layer, drawable);
    }

  /*  end the group undo  */
  gimp_image_undo_group_end (image);

  return layer;
}
static gboolean apply_watermark(watermark_settings settings, image_output out) 
{
    gboolean success = TRUE;
    gint32 layerId;
    gdouble posX, posY;
    gint wmwidth, wmheight, wmasc, wmdesc;
    
    if (settings->mode) {
        if (strlen(settings->text) == 0) {
            return TRUE;
        }
        
        GimpRGB old_foreground, new_foreground;
        
        gimp_context_get_foreground(&old_foreground);
        gimp_rgb_parse_hex (&new_foreground, gdk_color_to_string(&(settings->color)), strlen(gdk_color_to_string(&(settings->color))));
        gimp_context_set_foreground(&new_foreground);
        
        gimp_text_get_extents_fontname(
            settings->text,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font),
            &wmwidth,
            &wmheight,
            &wmasc,
            &wmdesc
        );

        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 5;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        layerId = gimp_text_fontname(
            out->image_id,
            -1,
            posX,
            posY,
            settings->text,
            -1,
            TRUE,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font)
        );
        gimp_context_set_foreground(&old_foreground);
        gimp_layer_set_opacity(layerId, settings->opacity);
    }
    else {
        if (!g_file_test(settings->image_file, G_FILE_TEST_IS_REGULAR)) {//((access(settings->image_file, R_OK) == -1)) {
            // error, can't access image file
            return TRUE;
        }
        
        layerId = gimp_file_load_layer(
            GIMP_RUN_NONINTERACTIVE,
            out->image_id,
            settings->image_file
        );
        
        gimp_layer_set_opacity(layerId, settings->opacity);
        wmwidth = gimp_drawable_width(layerId);
        wmheight = gimp_drawable_height(layerId);
        
        #if USE_API26
        
            gimp_image_add_layer(
                out->image_id,
                layerId,
                0
            );
        
        #else
        
            // starting from 2.8, gimp_image_add_layer is deprecated. 
            // use gimp_image_insert_layer instead
            gimp_image_insert_layer(
                out->image_id,
                layerId,
                0,
                0
            );
            
        #endif
        
        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 10;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        gimp_layer_set_offsets(
            layerId,
            posX,
            posY
        );   
    }
    
    // refresh all drawables
    g_free(out->drawable_ids);
    out->drawable_ids = gimp_image_get_layers(out->image_id, &out->drawable_count);
    
    return success;
}
static gboolean apply_resize(resize_settings settings, image_output out) 
{
    gboolean success = FALSE;
    gint orig_w, orig_h, final_w, final_h, view_w, view_h;
    gdouble orig_res_x, orig_res_y;
    
    if (settings->change_res) {
        success = gimp_image_get_resolution(
            out->image_id,
            &orig_res_x,
            &orig_res_y
        );
        
        if ((settings->new_res_x != orig_res_x) || (settings->new_res_y != orig_res_y)) {
            // change resolution 
            success = gimp_image_set_resolution(
                out->image_id,
                settings->new_res_x,
                settings->new_res_y
            );
        }
    }

    orig_w = gimp_image_width(out->image_id);
    orig_h = gimp_image_height(out->image_id);
    
    if (settings->resize_mode == RESIZE_PERCENT) {
        
        if (settings->stretch_mode == STRETCH_ASPECT) {
            gdouble newpct = min(settings->new_w_pc, settings->new_h_pc);
            
            final_w = view_w = round((orig_w * newpct) / 100.0);
            final_h = view_h = round((orig_h * newpct) / 100.0);
        }
        else if (settings->stretch_mode == STRETCH_PADDED) {
            gdouble newpct = min(settings->new_w_pc, settings->new_h_pc);
            
            final_w = round((orig_w * newpct) / 100.0);
            final_h = round((orig_h * newpct) / 100.0);
            view_w = round((orig_w * settings->new_w_pc) / 100.0);
            view_h = round((orig_h * settings->new_h_pc) / 100.0);
        }
        else {
            final_w = view_w = round((orig_w * settings->new_w_pc) / 100.0);
            final_h = view_h = round((orig_h * settings->new_h_pc) / 100.0);
        }
    }
    else {
        // user typed exact pixel size 
        if (settings->resize_mode == RESIZE_PIXEL_WIDTH) {
            view_w = settings->new_w_px; // width is fixed 
            
            if (settings->stretch_mode == STRETCH_ASPECT) {
                final_w = view_w;
                final_h = view_h = round(((float)final_w * orig_h) / orig_w);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                final_w = min(view_w, orig_w);
                final_h = round(((float)final_w * orig_h) / orig_w);
                view_h = max(orig_h, final_h);
            }
            else {
                final_w = view_w;
                final_h = view_h = orig_h;
            }
        }
        else if (settings->resize_mode == RESIZE_PIXEL_HEIGHT) {
            view_h = settings->new_h_px; // height is fixed
            
            if (settings->stretch_mode == STRETCH_ASPECT) {
                final_h = view_h;
                final_w = view_w = round(((float)final_h * orig_w) / orig_h);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                final_h = min(view_h, orig_h);
                final_w = round(((float)final_h * orig_w) / orig_h);
                view_w = max(orig_w, final_w);
            }
            else {
                final_h = view_h;
                final_w = view_w = orig_w;
            }
        }
        else {
            // both dimensions are defined 
            if (settings->stretch_mode == STRETCH_ASPECT) {
                // Find which new dimension is the smallest percentage of the existing image dimension
                gdouble newwpct = (float)settings->new_w_px / (float)orig_w;
                gdouble newhpct = (float)settings->new_h_px / (float)orig_h;
                gdouble newpct = min(newwpct, newhpct);

                final_w = view_w = round(orig_w * newpct);
                final_h = view_h = round(orig_h * newpct);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                // Find which new dimension is the smallest percentage of the existing image dimension
                gdouble newwpct = (float)settings->new_w_px / (float)orig_w;
                gdouble newhpct = (float)settings->new_h_px / (float)orig_h;
                gdouble newpct = min(newwpct, newhpct);
                
                final_w = round(orig_w * newpct);
                final_h = round(orig_h * newpct);
                view_w = round(orig_w * newwpct);
                view_h = round(orig_h * newhpct);
            }
            else {
                final_w = view_w = settings->new_w_px;
                final_h = view_h = settings->new_h_px;
            }
        }
    }
    
    // do resize 
    #if USE_API26
    
        success = gimp_image_scale_full (
            out->image_id, 
            final_w, 
            final_h, 
            settings->interpolation
        );
        
    #else
    
        // starting from 2.8, gimp_image_scale_full is deprecated. 
        // use gimp_image_scale instead
        GimpInterpolationType old_interpolation;
        old_interpolation = gimp_context_get_interpolation();
        
        success = gimp_context_set_interpolation (settings->interpolation);
        
        success = gimp_image_scale (
            out->image_id, 
            final_w, 
            final_h
        );
        
        success = gimp_context_set_interpolation (old_interpolation);
    
    #endif
    
    // add a padding if requested
    if (settings->stretch_mode == STRETCH_PADDED) {
        
        // the padding will be drawn using a coloured layer at the bottom of the image
        gint32 layerId = gimp_layer_new(
            out->image_id,
            "padding_layer",
            view_w, view_h,
            GIMP_RGBA_IMAGE,
            (settings->padding_color_alpha / (float)G_MAXUINT16) * 100,
            GIMP_NORMAL_MODE
        );
        
        #if USE_API26
        
            gimp_image_add_layer (
                out->image_id,
                layerId,
                0
            );
            
            gimp_image_lower_layer_to_bottom(out->image_id, layerId);
        
        #else
            
            gimp_image_insert_layer(
                out->image_id,
                layerId,
                0,
                0
            );
            
            gimp_image_lower_item_to_bottom(out->image_id, layerId);
            
        #endif
        
        // fill it with the selected color
        GimpRGB old_background, new_background;
            
        gimp_context_get_background(&old_background);
        gimp_rgb_parse_hex (&new_background, gdk_color_to_string(&(settings->padding_color)), strlen(gdk_color_to_string(&(settings->padding_color))));
        gimp_context_set_background(&new_background);
        gimp_drawable_fill(layerId, GIMP_BACKGROUND_FILL);
        gimp_context_set_background(&old_background);
        
        // move it to the center
        gimp_layer_translate(layerId, -abs(view_w - final_w) / 2, -abs(view_h - final_h) / 2);
        
        // finish changing the canvas size accordingly
        success = gimp_image_resize_to_layers(out->image_id);
    }
    
    return success;
}
示例#23
0
static void
gimp_display_shell_drop_pixbuf (GtkWidget *widget,
                                gint       x,
                                gint       y,
                                GdkPixbuf *pixbuf,
                                gpointer   data)
{
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image     = shell->display->image;
  GimpLayer        *new_layer;
  GimpImageType     image_type;
  gboolean          new_image = FALSE;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  switch (gdk_pixbuf_get_n_channels (pixbuf))
    {
    case 1: image_type = GIMP_GRAY_IMAGE;  break;
    case 2: image_type = GIMP_GRAYA_IMAGE; break;
    case 3: image_type = GIMP_RGB_IMAGE;   break;
    case 4: image_type = GIMP_RGBA_IMAGE;  break;
      break;

    default:
      g_return_if_reached ();
      break;
    }

  if (! image)
    {
      image = gimp_create_image (shell->display->gimp,
                                 gdk_pixbuf_get_width (pixbuf),
                                 gdk_pixbuf_get_height (pixbuf),
                                 GIMP_IMAGE_TYPE_BASE_TYPE (image_type),
                                 FALSE);

      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
      g_object_unref (image);

      gimp_image_undo_disable (image);

      new_image = TRUE;
    }

  new_layer =
    gimp_layer_new_from_pixbuf (pixbuf, image, image_type,
                                _("Dropped Buffer"),
                                GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

  if (new_layer)
    {
      GimpItem *new_item = GIMP_ITEM (new_layer);

      new_item = GIMP_ITEM (new_layer);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      if (! new_image)
        gimp_display_shell_dnd_position_item (shell, new_item);

      gimp_image_add_layer (image, new_layer, -1);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }

  if (new_image)
    gimp_image_undo_enable (image);
}
示例#24
0
static GimpLayer *
gimp_image_merge_layers (GimpImage     *image,
                         GSList        *merge_list,
                         GimpContext   *context,
                         GimpMergeType  merge_type,
                         const gchar   *undo_desc)
{
  GList           *list;
  GSList          *reverse_list = NULL;
  PixelRegion      src1PR, src2PR, maskPR;
  PixelRegion     *mask;
  GimpLayer       *merge_layer;
  GimpLayer       *layer;
  GimpLayer       *bottom_layer;
  GimpImageType    type;
  gint             count;
  gint             x1, y1, x2, y2;
  gint             x3, y3, x4, y4;
  CombinationMode  operation;
  gint             position;
  gboolean         active[MAX_CHANNELS] = { TRUE, TRUE, TRUE, TRUE };
  gint             off_x, off_y;
  gchar           *name;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);

  layer        = NULL;
  type         = GIMP_RGBA_IMAGE;
  x1 = y1      = 0;
  x2 = y2      = 0;
  bottom_layer = NULL;

  /*  Get the layer extents  */
  count = 0;
  while (merge_list)
    {
      layer = merge_list->data;

      gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);

      switch (merge_type)
        {
        case GIMP_EXPAND_AS_NECESSARY:
        case GIMP_CLIP_TO_IMAGE:
          if (! count)
            {
              x1 = off_x;
              y1 = off_y;
              x2 = off_x + gimp_item_width  (GIMP_ITEM (layer));
              y2 = off_y + gimp_item_height (GIMP_ITEM (layer));
            }
          else
            {
              if (off_x < x1)
                x1 = off_x;
              if (off_y < y1)
                y1 = off_y;
              if ((off_x + gimp_item_width (GIMP_ITEM (layer))) > x2)
                x2 = (off_x + gimp_item_width (GIMP_ITEM (layer)));
              if ((off_y + gimp_item_height (GIMP_ITEM (layer))) > y2)
                y2 = (off_y + gimp_item_height (GIMP_ITEM (layer)));
            }

          if (merge_type == GIMP_CLIP_TO_IMAGE)
            {
              x1 = CLAMP (x1, 0, gimp_image_get_width  (image));
              y1 = CLAMP (y1, 0, gimp_image_get_height (image));
              x2 = CLAMP (x2, 0, gimp_image_get_width  (image));
              y2 = CLAMP (y2, 0, gimp_image_get_height (image));
            }
          break;

        case GIMP_CLIP_TO_BOTTOM_LAYER:
          if (merge_list->next == NULL)
            {
              x1 = off_x;
              y1 = off_y;
              x2 = off_x + gimp_item_width (GIMP_ITEM (layer));
              y2 = off_y + gimp_item_height (GIMP_ITEM (layer));
            }
          break;

        case GIMP_FLATTEN_IMAGE:
          if (merge_list->next == NULL)
            {
              x1 = 0;
              y1 = 0;
              x2 = gimp_image_get_width  (image);
              y2 = gimp_image_get_height (image);
            }
          break;
        }

      count ++;
      reverse_list = g_slist_prepend (reverse_list, layer);
      merge_list = g_slist_next (merge_list);
    }

  if ((x2 - x1) == 0 || (y2 - y1) == 0)
    return NULL;

  /*  Start a merge undo group. */

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE,
                               undo_desc);

  name = g_strdup (gimp_object_get_name (GIMP_OBJECT (layer)));

  if (merge_type == GIMP_FLATTEN_IMAGE ||
      gimp_drawable_type (GIMP_DRAWABLE (layer)) == GIMP_INDEXED_IMAGE)
    {
      guchar bg[4] = { 0, 0, 0, 0 };

      type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (gimp_image_base_type (image));

      merge_layer = gimp_layer_new (image, (x2 - x1), (y2 - y1),
                                    type,
                                    gimp_object_get_name (GIMP_OBJECT (layer)),
                                    GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
      if (! merge_layer)
        {
          g_warning ("%s: could not allocate merge layer.", G_STRFUNC);
          return NULL;
        }

      GIMP_ITEM (merge_layer)->offset_x = x1;
      GIMP_ITEM (merge_layer)->offset_y = y1;

      /*  get the background for compositing  */
      gimp_image_get_background (image, context,
                                 gimp_drawable_type (GIMP_DRAWABLE (merge_layer)),
                                 bg);

      /*  init the pixel region  */
      pixel_region_init (&src1PR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (merge_layer)),
                         0, 0, (x2 - x1), (y2 - y1),
                         TRUE);

      /*  set the region to the background color  */
      color_region (&src1PR, bg);

      position = 0;
    }
  else
    {
      /*  The final merged layer inherits the name of the bottom most layer
       *  and the resulting layer has an alpha channel whether or not the
       *  original did. Opacity is set to 100% and the MODE is set to normal.
       */

      merge_layer =
        gimp_layer_new (image, (x2 - x1), (y2 - y1),
                        gimp_drawable_type_with_alpha (GIMP_DRAWABLE (layer)),
                        "merged layer",
                        GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

      if (!merge_layer)
        {
          g_warning ("%s: could not allocate merge layer", G_STRFUNC);
          return NULL;
        }

      GIMP_ITEM (merge_layer)->offset_x = x1;
      GIMP_ITEM (merge_layer)->offset_y = y1;

      /*  clear the layer  */
      pixel_region_init (&src1PR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (merge_layer)),
                         0, 0,
                         (x2 - x1), (y2 - y1),
                         TRUE);
      clear_region (&src1PR);

      /*  Find the index in the layer list of the bottom layer--we need this
       *  in order to add the final, merged layer to the layer list correctly
       */
      layer = reverse_list->data;
      position =
        gimp_container_num_children (image->layers) -
        gimp_container_get_child_index (image->layers, GIMP_OBJECT (layer));
    }

  bottom_layer = layer;

  /* Copy the tattoo and parasites of the bottom layer to the new layer */
  gimp_item_set_tattoo (GIMP_ITEM (merge_layer),
                        gimp_item_get_tattoo (GIMP_ITEM (bottom_layer)));

  g_object_unref (GIMP_ITEM (merge_layer)->parasites);
  GIMP_ITEM (merge_layer)->parasites =
    gimp_parasite_list_copy (GIMP_ITEM (bottom_layer)->parasites);

  while (reverse_list)
    {
      GimpLayerModeEffects  mode;

      layer = reverse_list->data;

      /*  determine what sort of operation is being attempted and
       *  if it's actually legal...
       */
      operation = gimp_image_merge_layers_get_operation (merge_layer, layer);

      if (operation == -1)
        {
          gimp_layer_add_alpha (layer);

          /*  try again ...  */
          operation = gimp_image_merge_layers_get_operation (merge_layer,
                                                             layer);
        }

      if (operation == -1)
        {
          g_warning ("%s: attempting to merge incompatible layers.", G_STRFUNC);
          return NULL;
        }

      gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);

      x3 = CLAMP (off_x, x1, x2);
      y3 = CLAMP (off_y, y1, y2);
      x4 = CLAMP (off_x + gimp_item_width  (GIMP_ITEM (layer)), x1, x2);
      y4 = CLAMP (off_y + gimp_item_height (GIMP_ITEM (layer)), y1, y2);

      /* configure the pixel regions  */
      pixel_region_init (&src1PR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (merge_layer)),
                         (x3 - x1), (y3 - y1), (x4 - x3), (y4 - y3),
                         TRUE);
      pixel_region_init (&src2PR,
                         gimp_drawable_get_tiles (GIMP_DRAWABLE (layer)),
                         (x3 - off_x), (y3 - off_y),
                         (x4 - x3), (y4 - y3),
                         FALSE);

      if (gimp_layer_get_mask (layer) &&
          gimp_layer_mask_get_apply (layer->mask))
        {
          TileManager *tiles;

          tiles = gimp_drawable_get_tiles (GIMP_DRAWABLE (layer->mask));

          pixel_region_init (&maskPR, tiles,
                             (x3 - off_x), (y3 - off_y), (x4 - x3), (y4 - y3),
                             FALSE);
          mask = &maskPR;
        }
      else
        {
          mask = NULL;
        }

      /* DISSOLVE_MODE is special since it is the only mode that does not
       *  work on the projection with the lower layer, but only locally on
       *  the layers alpha channel.
       */
      mode = gimp_layer_get_mode (layer);
      if (layer == bottom_layer && mode != GIMP_DISSOLVE_MODE)
        mode = GIMP_NORMAL_MODE;

      combine_regions (&src1PR, &src2PR, &src1PR, mask, NULL,
                       gimp_layer_get_opacity (layer) * 255.999,
                       mode,
                       active,
                       operation);

      gimp_image_remove_layer (image, layer);

      reverse_list = g_slist_next (reverse_list);
    }

  g_slist_free (reverse_list);

  /*  if the type is flatten, remove all the remaining layers  */
  if (merge_type == GIMP_FLATTEN_IMAGE)
    {
      list = GIMP_LIST (image->layers)->list;
      while (list)
        {
          layer = list->data;

          list = g_list_next (list);
          gimp_image_remove_layer (image, layer);
        }

      gimp_image_add_layer (image, merge_layer, position);
    }
  else
    {
      /*  Add the layer to the image  */
      gimp_image_add_layer (image, merge_layer,
         gimp_container_num_children (image->layers) - position + 1);
    }

  /* set the name after the original layers have been removed so we
   * don't end up with #2 appended to the name
   */
  gimp_object_take_name (GIMP_OBJECT (merge_layer), name);

  gimp_item_set_visible (GIMP_ITEM (merge_layer), TRUE, TRUE);

  /*  End the merge undo group  */
  gimp_image_undo_group_end (image);

  gimp_drawable_update (GIMP_DRAWABLE (merge_layer),
                        0, 0,
                        gimp_item_width  (GIMP_ITEM (merge_layer)),
                        gimp_item_height (GIMP_ITEM (merge_layer)));

  return merge_layer;
}
示例#25
0
static GimpLayer *
gimp_image_merge_layers (GimpImage     *image,
                         GimpContainer *container,
                         GSList        *merge_list,
                         GimpContext   *context,
                         GimpMergeType  merge_type)
{
  GList            *list;
  GSList           *reverse_list = NULL;
  GSList           *layers;
  GimpLayer        *merge_layer;
  GimpLayer        *layer;
  GimpLayer        *bottom_layer;
  GimpParasiteList *parasites;
  gint              count;
  gint              x1, y1, x2, y2;
  gint              off_x, off_y;
  gint              position;
  gchar            *name;
  GimpLayer        *parent;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);

  layer        = NULL;
  x1 = y1      = 0;
  x2 = y2      = 0;
  bottom_layer = NULL;

  parent = gimp_layer_get_parent (merge_list->data);

  /*  Get the layer extents  */
  count = 0;
  while (merge_list)
    {
      layer = merge_list->data;

      gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);

      switch (merge_type)
        {
        case GIMP_EXPAND_AS_NECESSARY:
        case GIMP_CLIP_TO_IMAGE:
          if (! count)
            {
              x1 = off_x;
              y1 = off_y;
              x2 = off_x + gimp_item_get_width  (GIMP_ITEM (layer));
              y2 = off_y + gimp_item_get_height (GIMP_ITEM (layer));
            }
          else
            {
              if (off_x < x1)
                x1 = off_x;
              if (off_y < y1)
                y1 = off_y;
              if ((off_x + gimp_item_get_width (GIMP_ITEM (layer))) > x2)
                x2 = (off_x + gimp_item_get_width (GIMP_ITEM (layer)));
              if ((off_y + gimp_item_get_height (GIMP_ITEM (layer))) > y2)
                y2 = (off_y + gimp_item_get_height (GIMP_ITEM (layer)));
            }

          if (merge_type == GIMP_CLIP_TO_IMAGE)
            {
              x1 = CLAMP (x1, 0, gimp_image_get_width  (image));
              y1 = CLAMP (y1, 0, gimp_image_get_height (image));
              x2 = CLAMP (x2, 0, gimp_image_get_width  (image));
              y2 = CLAMP (y2, 0, gimp_image_get_height (image));
            }
          break;

        case GIMP_CLIP_TO_BOTTOM_LAYER:
          if (merge_list->next == NULL)
            {
              x1 = off_x;
              y1 = off_y;
              x2 = off_x + gimp_item_get_width  (GIMP_ITEM (layer));
              y2 = off_y + gimp_item_get_height (GIMP_ITEM (layer));
            }
          break;

        case GIMP_FLATTEN_IMAGE:
          if (merge_list->next == NULL)
            {
              x1 = 0;
              y1 = 0;
              x2 = gimp_image_get_width  (image);
              y2 = gimp_image_get_height (image);
            }
          break;
        }

      count ++;
      reverse_list = g_slist_prepend (reverse_list, layer);
      merge_list = g_slist_next (merge_list);
    }

  if ((x2 - x1) == 0 || (y2 - y1) == 0)
    return NULL;

  /*  Start a merge undo group. */

  name = g_strdup (gimp_object_get_name (layer));

  if (merge_type == GIMP_FLATTEN_IMAGE ||
      (gimp_drawable_is_indexed (GIMP_DRAWABLE (layer)) &&
       ! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer))))
    {
      GeglColor *color;
      GimpRGB    bg;

      merge_layer = gimp_layer_new (image, (x2 - x1), (y2 - y1),
                                    gimp_image_get_layer_format (image, FALSE),
                                    gimp_object_get_name (layer),
                                    GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
      if (! merge_layer)
        {
          g_warning ("%s: could not allocate merge layer.", G_STRFUNC);
          return NULL;
        }

      gimp_item_set_offset (GIMP_ITEM (merge_layer), x1, y1);

      /*  get the background for compositing  */
      gimp_context_get_background (context, &bg);

      color = gimp_gegl_color_new (&bg);
      gegl_buffer_set_color (gimp_drawable_get_buffer (GIMP_DRAWABLE (merge_layer)),
                             GEGL_RECTANGLE(0,0,x2-x1,y2-y1), color);
      g_object_unref (color);

      position = 0;
    }
  else
    {
      /*  The final merged layer inherits the name of the bottom most layer
       *  and the resulting layer has an alpha channel whether or not the
       *  original did. Opacity is set to 100% and the MODE is set to normal.
       */

      merge_layer =
        gimp_layer_new (image, (x2 - x1), (y2 - y1),
                        gimp_drawable_get_format_with_alpha (GIMP_DRAWABLE (layer)),
                        "merged layer",
                        GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

      if (!merge_layer)
        {
          g_warning ("%s: could not allocate merge layer", G_STRFUNC);
          return NULL;
        }

      gimp_item_set_offset (GIMP_ITEM (merge_layer), x1, y1);

      /*  clear the layer  */
      gegl_buffer_clear (gimp_drawable_get_buffer (GIMP_DRAWABLE (merge_layer)),
                         NULL);

      /*  Find the index in the layer list of the bottom layer--we need this
       *  in order to add the final, merged layer to the layer list correctly
       */
      layer = reverse_list->data;
      position =
        gimp_container_get_n_children (container) -
        gimp_container_get_child_index (container, GIMP_OBJECT (layer));
    }

  bottom_layer = layer;

  /* Copy the tattoo and parasites of the bottom layer to the new layer */
  gimp_item_set_tattoo (GIMP_ITEM (merge_layer),
                        gimp_item_get_tattoo (GIMP_ITEM (bottom_layer)));

  parasites = gimp_item_get_parasites (GIMP_ITEM (bottom_layer));
  parasites = gimp_parasite_list_copy (parasites);
  gimp_item_set_parasites (GIMP_ITEM (merge_layer), parasites);
  g_object_unref (parasites);

  for (layers = reverse_list; layers; layers = g_slist_next (layers))
    {
      GeglBuffer           *merge_buffer;
      GeglBuffer           *layer_buffer;
      GimpApplicator       *applicator;
      GimpLayerModeEffects  mode;

      layer = layers->data;

      gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);

      /* DISSOLVE_MODE is special since it is the only mode that does not
       *  work on the projection with the lower layer, but only locally on
       *  the layers alpha channel.
       */
      mode = gimp_layer_get_mode (layer);
      if (layer == bottom_layer && mode != GIMP_DISSOLVE_MODE)
        mode = GIMP_NORMAL_MODE;

      merge_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (merge_layer));
      layer_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));

      applicator =
        gimp_applicator_new (NULL,
                             gimp_drawable_get_linear (GIMP_DRAWABLE (layer)),
                             FALSE, FALSE);

      if (gimp_layer_get_mask (layer) &&
          gimp_layer_get_apply_mask (layer))
        {
          GeglBuffer *mask_buffer;

          mask_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer->mask));

          gimp_applicator_set_mask_buffer (applicator, mask_buffer);
          gimp_applicator_set_mask_offset (applicator,
                                           - (x1 - off_x),
                                           - (y1 - off_y));
        }

      gimp_applicator_set_src_buffer (applicator, merge_buffer);
      gimp_applicator_set_dest_buffer (applicator, merge_buffer);

      gimp_applicator_set_apply_buffer (applicator, layer_buffer);
      gimp_applicator_set_apply_offset (applicator,
                                        - (x1 - off_x),
                                        - (y1 - off_y));

      gimp_applicator_set_mode (applicator,
                                gimp_layer_get_opacity (layer),
                                mode);

      gimp_applicator_blit (applicator,
                            GEGL_RECTANGLE (0, 0,
                                            gegl_buffer_get_width  (merge_buffer),
                                            gegl_buffer_get_height (merge_buffer)));

      g_object_unref (applicator);

      gimp_image_remove_layer (image, layer, TRUE, NULL);
    }

  g_slist_free (reverse_list);

  gimp_object_take_name (GIMP_OBJECT (merge_layer), name);
  gimp_item_set_visible (GIMP_ITEM (merge_layer), TRUE, FALSE);

  /*  if the type is flatten, remove all the remaining layers  */
  if (merge_type == GIMP_FLATTEN_IMAGE)
    {
      list = gimp_image_get_layer_iter (image);
      while (list)
        {
          layer = list->data;

          list = g_list_next (list);
          gimp_image_remove_layer (image, layer, TRUE, NULL);
        }

      gimp_image_add_layer (image, merge_layer, parent,
                            position, TRUE);
    }
  else
    {
      /*  Add the layer to the image  */

      gimp_image_add_layer (image, merge_layer, parent,
                            gimp_container_get_n_children (container) -
                            position + 1,
                            TRUE);
    }

  gimp_drawable_update (GIMP_DRAWABLE (merge_layer),
                        0, 0,
                        gimp_item_get_width  (GIMP_ITEM (merge_layer)),
                        gimp_item_get_height (GIMP_ITEM (merge_layer)));

  return merge_layer;
}
示例#26
0
void ptRun(const gchar*     Name,
           gint       NrParameters,
           const GimpParam* Parameter,
           gint *nreturn_vals,
           GimpParam **return_vals) {
  printf("(%s,%d) '%s'\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
  printf("Name         : '%s'\n",Name);
  printf("NrParameters : %d\n",NrParameters);
  if (!strcmp(Name,"photivoSendToGimp")) {
    printf("RunMode      : %d\n",Parameter[0].data.d_int32);
    printf("FileName1    : '%s'\n",Parameter[1].data.d_string);
    printf("FileName2    : '%s'\n",Parameter[2].data.d_string);

    QFile GimpFile(Parameter[1].data.d_string);
    bool result = GimpFile.open(QIODevice::ReadOnly | QIODevice::Text);
    assert(result);

    QTextStream In(&GimpFile);

    QString ImageFileName = In.readLine();
    QString ExifFileName  = In.readLine();
    QString ICCFileName   = In.readLine();

    // Read image
    FILE *InputFile = fopen(ImageFileName.toLocal8Bit().data(),"rb");
    if (!InputFile) {
      ptLogError(1,ImageFileName.toLocal8Bit().data());
      return; // ptError_FileOpen;
    }

    short    Colors;
    unsigned short Width;
    unsigned short Height;
    unsigned short BitsPerColor;
    char     Buffer[128];

    // Extremely naive. Probably just enough for testcases.
    char *s = fgets(Buffer,127,InputFile);
    assert ( s );
    int n = sscanf(Buffer,"P%hd",&Colors);
    assert ( 1 == n );
    assert(Colors == 6 );
    do {
      s = fgets(Buffer,127,InputFile);
      assert ( s );
    } while (Buffer[0] == '#');
    sscanf(Buffer,"%hd %hd",&Width,&Height);
    s = fgets(Buffer,127,InputFile);
    assert ( s );
    sscanf(Buffer,"%hd",&BitsPerColor);
    assert(BitsPerColor == 0xffff);

    Colors = 3;

    unsigned short (* ImageForGimp)[3] =
      (unsigned short (*)[3]) CALLOC2(Width*Height,sizeof(*ImageForGimp));
    ptMemoryError(ImageForGimp,__FILE__,__LINE__);

    unsigned short*  PpmRow = (unsigned short *) CALLOC2(Width*Height,sizeof(*PpmRow));
    ptMemoryError(PpmRow,__FILE__,__LINE__);

    for (unsigned short Row=0; Row<Height; Row++) {
      size_t RV = fread(PpmRow,Colors*2,Width,InputFile);
      if (RV != (size_t) Width) {
        printf("ReadPpm error. Expected %d bytes. Got %d\n",Width,(int)RV);
        exit(EXIT_FAILURE);
      }
      if (htons(0x55aa) != 0x55aa) {
        swab((char *)PpmRow,(char *)PpmRow,Width*Colors*2);
      }
      for (unsigned short Col=0; Col<Width; Col++) {
        for (short c=0;c<3;c++) {
          ImageForGimp[Row*Width+Col][c] = PpmRow[Col*Colors+c];
        }
      }
    }

    FREE2(PpmRow);
    FCLOSE(InputFile);

    QFile ExifFile(ExifFileName);
    result = ExifFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize = ExifFile.size();
    QDataStream ExifIn(&ExifFile);
    char* ExifBuffer = (char *) MALLOC2(FileSize);
    ptMemoryError(ExifBuffer,__FILE__,__LINE__);
    unsigned ExifBufferLength = ExifIn.readRawData(ExifBuffer,FileSize);
    ExifFile.close();

    QFile ICCFile(ICCFileName);
    result = ICCFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize2 = ICCFile.size();
    QDataStream ICCIn(&ICCFile);
    char* ICCBuffer = (char *) MALLOC2(FileSize2);
    ptMemoryError(ICCBuffer,__FILE__,__LINE__);
    unsigned ICCBufferLength = ICCIn.readRawData(ICCBuffer,FileSize2);
    ICCFile.close();

    // And now copy to gimp.
    gint32 GimpImage = gimp_image_new(Width,
                                      Height,
                                      GIMP_RGB);
    assert (GimpImage != -1);
    gint32 GimpLayer = gimp_layer_new(GimpImage,
                                      "BG",
                                      Width,
                                      Height,
                                      GIMP_RGB_IMAGE,
                                      100.0,
                                      GIMP_NORMAL_MODE);
#if GIMP_MINOR_VERSION<=6
    gimp_image_add_layer(GimpImage,GimpLayer,0);
#else
    gimp_image_insert_layer(GimpImage,GimpLayer,0,0);
#endif
    GimpDrawable* Drawable = gimp_drawable_get(GimpLayer);
    GimpPixelRgn PixelRegion;
    gimp_pixel_rgn_init(&PixelRegion,
                        Drawable,
                        0,
                        0,
                        Drawable->width,
                        Drawable->height,
                        true,
                        false);
    unsigned short TileHeight = gimp_tile_height();
    for (unsigned short Row=0; Row<Height; Row+=TileHeight) {
      unsigned short NrRows = MIN(Height-Row, (int)TileHeight);
      guint8* Buffer = g_new(guint8,TileHeight*Width*3);
      for (unsigned short i=0; i<NrRows; i++) {
        for (unsigned short j=0; j<Width; j++) {
          for (short c=0;c<3;c++) {
            Buffer[3*(i*Width+j)+c] =
              ImageForGimp[(Row+i)*Width+j][c]>>8;
          }
        }
      }
      gimp_pixel_rgn_set_rect(&PixelRegion,
                              Buffer,
                              0,
                              Row,
                              Width,
                              NrRows);
      g_free(Buffer);
    }
    gimp_drawable_flush(Drawable);
    gimp_drawable_detach(Drawable);
    FREE2(ImageForGimp);
    GimpParasite* GimpExifData = gimp_parasite_new("exif-data",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ExifBufferLength,
                                                   ExifBuffer);
    gimp_image_parasite_attach(GimpImage,GimpExifData);
    gimp_parasite_free(GimpExifData);
    FREE2(ExifBuffer);

    GimpParasite* GimpICCData = gimp_parasite_new("icc-profile",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ICCBufferLength,
                                                   ICCBuffer);
    gimp_image_parasite_attach(GimpImage,GimpICCData);
    gimp_parasite_free(GimpICCData);
    FREE2(ICCBuffer);

    static GimpParam Values[2];
    *nreturn_vals = 2;
    *return_vals = Values;
    Values[0].type = GIMP_PDB_STATUS;
    Values[0].data.d_status = GIMP_PDB_SUCCESS;
    Values[1].type = GIMP_PDB_IMAGE;
    Values[1].data.d_image = GimpImage;

    QFile::remove(ImageFileName);
    QFile::remove(ExifFileName);
    QFile::remove(ICCFileName);
    QFile::remove(Parameter[1].data.d_string);

  }
示例#27
0
文件: dog.c 项目: Amerekanets/gimp
static void
dog (gint32        image_ID,
     GimpDrawable *drawable,
     gdouble       inner,
     gdouble       outer,
     gboolean      show_progress)
{
  GimpDrawable *drawable1;
  GimpDrawable *drawable2;
  gint32        drawable_id = drawable->drawable_id;
  gint32        layer1;
  gint32        layer2;
  gint          width, height;
  gint          x1, y1, x2, y2;
  guchar        maxval = 255;

  gimp_drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);

  width  = (x2 - x1);
  height = (y2 - y1);

  gimp_drawable_flush (drawable);

  layer1 = gimp_layer_copy (drawable_id);
  gimp_drawable_set_visible (layer1, FALSE);
  gimp_drawable_set_name (layer1, "dog_scratch_layer1");
  gimp_image_add_layer (image_ID, layer1, 0);

  layer2 = gimp_layer_copy (drawable_id);
  gimp_drawable_set_visible (layer2, FALSE);
  gimp_drawable_set_name (layer2, "dog_scratch_layer2");
  gimp_image_add_layer (image_ID, layer2, 0);

  drawable1 = gimp_drawable_get (layer1);
  drawable2 = gimp_drawable_get (layer2);

  gauss_rle (drawable1, inner, 0, show_progress);
  gauss_rle (drawable2, outer, 1, show_progress);

  compute_difference (drawable, drawable1, drawable2, &maxval);

  gimp_drawable_detach (drawable1);
  gimp_drawable_detach (drawable2);

  gimp_image_remove_layer (image_ID, layer1);
  gimp_image_remove_layer (image_ID, layer2);

  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable_id, TRUE);
  gimp_drawable_update (drawable_id, x1, y1, width, height);

  if (dogvals.normalize)
    {
      normalize (drawable, maxval);
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable_id, TRUE);
      gimp_drawable_update (drawable_id, x1, y1, width, height);
    }

  if (dogvals.invert)
    gimp_invert (drawable_id);
}
示例#28
0
static void
gimp_display_shell_drop_drawable (GtkWidget    *widget,
                                  gint          x,
                                  gint          y,
                                  GimpViewable *viewable,
                                  gpointer      data)
{
  GimpDisplayShell *shell     = GIMP_DISPLAY_SHELL (data);
  GimpImage        *image     = shell->display->image;
  GType             new_type;
  GimpItem         *new_item;
  gboolean          new_image = FALSE;

  GIMP_LOG (DND, NULL);

  if (shell->display->gimp->busy)
    return;

  if (! image)
    {
      GimpImage         *src_image = gimp_item_get_image (GIMP_ITEM (viewable));
      GimpDrawable      *drawable  = GIMP_DRAWABLE (viewable);
      GimpImageBaseType  type;
      gdouble            xres;
      gdouble            yres;

      type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable));

      image = gimp_create_image (shell->display->gimp,
                                 gimp_item_width (GIMP_ITEM (viewable)),
                                 gimp_item_height (GIMP_ITEM (viewable)),
                                 type, TRUE);
      gimp_image_undo_disable (image);

      if (type == GIMP_INDEXED)
        gimp_image_set_colormap (image,
                                 gimp_image_get_colormap (src_image),
                                 gimp_image_get_colormap_size (src_image),
                                 FALSE);

      gimp_image_get_resolution (src_image, &xres, &yres);
      gimp_image_set_resolution (image, xres, yres);
      gimp_image_set_unit (image, gimp_image_get_unit (src_image));

      gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0);
      g_object_unref (image);

      new_image = TRUE;
    }

  if (GIMP_IS_LAYER (viewable))
    new_type = G_TYPE_FROM_INSTANCE (viewable);
  else
    new_type = GIMP_TYPE_LAYER;

  new_item = gimp_item_convert (GIMP_ITEM (viewable), image, new_type);

  if (new_item)
    {
      GimpLayer *new_layer = GIMP_LAYER (new_item);

      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                                   _("Drop New Layer"));

      if (! new_image)
        gimp_display_shell_dnd_position_item (shell, new_item);

      gimp_item_set_visible (new_item, TRUE, FALSE);
      gimp_item_set_linked (new_item, FALSE, FALSE);

      gimp_image_add_layer (image, new_layer, -1);

      gimp_image_undo_group_end (image);

      gimp_display_shell_dnd_flush (shell, image);
    }

  if (new_image)
    gimp_image_undo_enable (image);
}
示例#29
0
GimpLayer *
gimp_edit_paste (GimpImage    *image,
                 GimpDrawable *drawable,
                 GimpBuffer   *paste,
                 gboolean      paste_into,
                 gint          viewport_x,
                 gint          viewport_y,
                 gint          viewport_width,
                 gint          viewport_height)
{
  GimpLayer  *layer;
  const Babl *format;
  gint        image_width;
  gint        image_height;
  gint        width;
  gint        height;
  gint        offset_x;
  gint        offset_y;
  gboolean    clamp_to_image = TRUE;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
  g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (drawable == NULL ||
                        gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
  g_return_val_if_fail (GIMP_IS_BUFFER (paste), NULL);

  /*  Make a new layer: if drawable == NULL,
   *  user is pasting into an empty image.
   */

  if (drawable)
    format = gimp_drawable_get_format_with_alpha (drawable);
  else
    format = gimp_image_get_layer_format (image, TRUE);

  layer = gimp_layer_new_from_buffer (paste, image,
                                      format,
                                      _("Pasted Layer"),
                                      GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

  if (! layer)
    return NULL;

  image_width  = gimp_image_get_width  (image);
  image_height = gimp_image_get_height (image);

  width  = gimp_item_get_width  (GIMP_ITEM (layer));
  height = gimp_item_get_height (GIMP_ITEM (layer));

  if (viewport_width  == image_width &&
      viewport_height == image_height)
    {
      /* if the whole image is visible, act as if there was no viewport */

      viewport_x      = 0;
      viewport_y      = 0;
      viewport_width  = 0;
      viewport_height = 0;
    }

  if (drawable)
    {
      /*  if pasting to a drawable  */

      gint     off_x, off_y;
      gint     x1, y1, x2, y2;
      gint     paste_x, paste_y;
      gint     paste_width, paste_height;
      gboolean have_mask;

      gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
      have_mask = gimp_item_mask_bounds (GIMP_ITEM (drawable),
                                         &x1, &y1, &x2, &y2);

      if (! have_mask         && /* if we have no mask */
          viewport_width  > 0 && /* and we have a viewport */
          viewport_height > 0 &&
          (width  < (x2 - x1) || /* and the paste is smaller than the target */
           height < (y2 - y1)) &&

          /* and the viewport intersects with the target */
          gimp_rectangle_intersect (viewport_x, viewport_y,
                                    viewport_width, viewport_height,
                                    off_x, off_y,
                                    x2 - x1, y2 - y1,
                                    &paste_x, &paste_y,
                                    &paste_width, &paste_height))
        {
          /*  center on the viewport  */

          offset_x = paste_x + (paste_width - width)  / 2;
          offset_y = paste_y + (paste_height- height) / 2;
        }
      else
        {
          /*  otherwise center on the target  */

          offset_x = off_x + ((x1 + x2) - width)  / 2;
          offset_y = off_y + ((y1 + y2) - height) / 2;

          /*  and keep it that way  */
          clamp_to_image = FALSE;
        }
    }
  else if (viewport_width  > 0 &&  /* if we have a viewport */
           viewport_height > 0 &&
           (width  < image_width || /* and the paste is       */
            height < image_height)) /* smaller than the image */
    {
      /*  center on the viewport  */

      offset_x = viewport_x + (viewport_width  - width)  / 2;
      offset_y = viewport_y + (viewport_height - height) / 2;
    }
  else
    {
      /*  otherwise center on the image  */

      offset_x = (image_width  - width)  / 2;
      offset_y = (image_height - height) / 2;

      /*  and keep it that way  */
      clamp_to_image = FALSE;
    }

  if (clamp_to_image)
    {
      /*  Ensure that the pasted layer is always within the image, if it
       *  fits and aligned at top left if it doesn't. (See bug #142944).
       */
      offset_x = MIN (offset_x, image_width  - width);
      offset_y = MIN (offset_y, image_height - height);
      offset_x = MAX (offset_x, 0);
      offset_y = MAX (offset_y, 0);
    }

  gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y);

  /*  Start a group undo  */
  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                               C_("undo-type", "Paste"));

  /*  If there is a selection mask clear it--
   *  this might not always be desired, but in general,
   *  it seems like the correct behavior.
   */
  if (! gimp_channel_is_empty (gimp_image_get_mask (image)) && ! paste_into)
    gimp_channel_clear (gimp_image_get_mask (image), NULL, TRUE);

  /*  if there's a drawable, add a new floating selection  */
  if (drawable)
    floating_sel_attach (layer, drawable);
  else
    gimp_image_add_layer (image, layer, NULL, 0, TRUE);

  /*  end the group undo  */
  gimp_image_undo_group_end (image);

  return layer;
}
示例#30
0
 /* ---------------------------------
  * gap_edgeDetectionByBlurDiff
  * ---------------------------------
  */
 gint32
 gap_edgeDetectionByBlurDiff(gint32 activeDrawableId, gdouble blurRadius, gdouble blurResultRadius
   , gdouble threshold, gint32 shift, gboolean doLevelsAutostretch
   , gboolean invert)
 {
   gint32 blurLayerId;
   gint32 edgeLayerId;
   gint32 imageId;
   GimpDrawable *edgeDrawable;
   GimpDrawable *refDrawable;
   GimpDrawable *blurDrawable;

 
 
 
   imageId = gimp_drawable_get_image(activeDrawableId);
 
   edgeLayerId = gimp_layer_copy(activeDrawableId);
   gimp_image_add_layer (imageId, edgeLayerId, 0 /* stackposition */ );
 
   edgeDrawable = gimp_drawable_get(edgeLayerId);
   refDrawable = gimp_drawable_get(activeDrawableId);
 
   if(blurRadius > 0.0)
   {
     p_call_plug_in_gauss_iir2(imageId, edgeLayerId, blurRadius, blurRadius);
   }
   
   blurDrawable = NULL;
//    blurLayerId = gimp_layer_copy(edgeLayerId);
//    gimp_image_add_layer (imageId, blurLayerId, 0 /* stackposition */ );
//    blurDrawable = gimp_drawable_get(blurLayerId);

   p_subtract_ref_layer(imageId, edgeDrawable, refDrawable, threshold, shift, invert);
   //p_subtract_ref_layer(imageId, edgeDrawable, blurDrawable, threshold, shift, invert);
   if (doLevelsAutostretch)
   {
     gimp_levels_stretch(edgeLayerId);
   }

   if(blurResultRadius > 0.0)
   {
     p_call_plug_in_gauss_iir2(imageId, edgeLayerId, blurResultRadius, blurResultRadius);
   }
 
   if(refDrawable)
   {
     gimp_drawable_detach(refDrawable);
   }
   
   if(edgeDrawable)
   {
     gimp_drawable_detach(edgeDrawable);
   }
   if(blurDrawable)
   {
     gimp_drawable_detach(blurDrawable);
   }
 
   return (edgeLayerId);
   
 }  /* end gap_edgeDetectionByBlurDiff */