示例#1
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);
}
示例#2
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."));
    }
}
示例#3
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;
}
示例#4
0
GimpDrawable *
gimp_drawable_transform_paste (GimpDrawable *drawable,
                               GeglBuffer   *buffer,
                               gint          offset_x,
                               gint          offset_y,
                               gboolean      new_layer)
{
  GimpImage   *image;
  GimpLayer   *layer     = NULL;
  const gchar *undo_desc = NULL;

  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  if (GIMP_IS_LAYER (drawable))
    undo_desc = C_("undo-type", "Transform Layer");
  else if (GIMP_IS_CHANNEL (drawable))
    undo_desc = C_("undo-type", "Transform Channel");
  else
    return NULL;

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, undo_desc);

  if (new_layer)
    {
      layer =
        gimp_layer_new_from_buffer (buffer, image,
                                    gimp_drawable_get_format_with_alpha (drawable),
                                    _("Transformation"),
                                    GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);

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

      floating_sel_attach (layer, drawable);

      drawable = GIMP_DRAWABLE (layer);
    }
  else
    {
      gimp_drawable_set_buffer_full (drawable, TRUE, NULL,
                                     buffer,
                                     offset_x, offset_y);
    }

  gimp_image_undo_group_end (image);

  return drawable;
}
示例#5
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;
}
示例#6
0
GimpLayer *
gimp_edit_paste (GimpImage     *image,
                 GimpDrawable  *drawable,
                 GimpObject    *paste,
                 GimpPasteType  paste_type,
                 gint           viewport_x,
                 gint           viewport_y,
                 gint           viewport_width,
                 gint           viewport_height)
{
  GimpLayer  *layer = NULL;
  const Babl *floating_format;
  gint        offset_x;
  gint        offset_y;

  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_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);

  /*  change paste type to NEW_LAYER for cases where we can't attach a
   *  floating selection
   */
  if (! drawable                                            ||
      gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
      gimp_item_is_content_locked (GIMP_ITEM (drawable)))
    {
      paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
    }

  /*  floating pastes always have the pasted-to drawable's format with
   *  alpha; if drawable == NULL, user is pasting into an empty image
   */
  if (drawable)
    floating_format = gimp_drawable_get_format_with_alpha (drawable);
  else
    floating_format = gimp_image_get_layer_format (image, TRUE);

  if (GIMP_IS_IMAGE (paste))
    {
      GType layer_type;

      layer = gimp_image_get_layer_iter (GIMP_IMAGE (paste))->data;

      switch (paste_type)
        {
        case GIMP_PASTE_TYPE_FLOATING:
        case GIMP_PASTE_TYPE_FLOATING_INTO:
          /*  when pasting as floating selection, force creation of a
           *  plain layer, so gimp_item_convert() will collapse a
           *  group layer
           */
          layer_type = GIMP_TYPE_LAYER;
          break;

        case GIMP_PASTE_TYPE_NEW_LAYER:
          layer_type = G_TYPE_FROM_INSTANCE (layer);
          break;

        default:
          g_return_val_if_reached (NULL);
        }

      layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (layer),
                                             image, layer_type));

      switch (paste_type)
        {
        case GIMP_PASTE_TYPE_FLOATING:
        case GIMP_PASTE_TYPE_FLOATING_INTO:
          /*  when pasting as floating selection, get rid of the layer mask,
           *  and make sure the layer has the right format
           */
          if (gimp_layer_get_mask (layer))
            gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);

          if (gimp_drawable_get_format (GIMP_DRAWABLE (layer)) !=
              floating_format)
            {
              gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image,
                                          gimp_drawable_get_base_type (drawable),
                                          gimp_drawable_get_precision (drawable),
                                          TRUE,
                                          NULL,
                                          GEGL_DITHER_NONE, GEGL_DITHER_NONE,
                                          FALSE, NULL);
            }
          break;

        default:
          break;
        }
    }
  else if (GIMP_IS_BUFFER (paste))
    {
      layer = gimp_layer_new_from_buffer (GIMP_BUFFER (paste), image,
                                          floating_format,
                                          _("Pasted Layer"),
                                          GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
    }

  if (! layer)
    return NULL;

  gimp_edit_get_paste_offset (image, drawable, GIMP_OBJECT (layer),
                              viewport_x,
                              viewport_y,
                              viewport_width,
                              viewport_height,
                              &offset_x,
                              &offset_y);
  gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y);

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
                               C_("undo-type", "Paste"));

  switch (paste_type)
    {
    case GIMP_PASTE_TYPE_FLOATING:
      /*  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);

      /* fall thru */

    case GIMP_PASTE_TYPE_FLOATING_INTO:
      floating_sel_attach (layer, drawable);
      break;

    case GIMP_PASTE_TYPE_NEW_LAYER:
      {
        GimpLayer *parent   = NULL;
        gint       position = 0;

        /* always add on top of the passed layer, where we would
         * attach a floating selection
         */
        if (GIMP_IS_LAYER (drawable))
          {
            parent   = gimp_layer_get_parent (GIMP_LAYER (drawable));
            position = gimp_item_get_index (GIMP_ITEM (drawable));
          }

        gimp_image_add_layer (image, layer, parent, position, TRUE);
      }
      break;
    }

  gimp_image_undo_group_end (image);

  return layer;
}