Exemplo n.º 1
0
static gboolean
webx_pipeline_check_update (WebxPipeline *pipeline)
{
  gint *layers;
  gint  num_layers;
  gint  i;

  g_return_val_if_fail (WEBX_IS_PIPELINE (pipeline), FALSE);

  if (pipeline->rgb_image != -1)
    {
      gimp_image_delete (pipeline->rgb_image);
      pipeline->rgb_image = -1;
    }
  if (pipeline->indexed_image != -1)
    {
      gimp_image_delete (pipeline->indexed_image);
      pipeline->indexed_image = -1;
    }
  if (pipeline->background)
    {
      g_object_unref (pipeline->background);
      pipeline->background = NULL;
    }

  pipeline->rgb_image = gimp_image_duplicate (pipeline->user_image);
  gimp_image_undo_disable (pipeline->rgb_image);
  pipeline->rgb_layer =
    gimp_image_merge_visible_layers (pipeline->rgb_image,
                                     GIMP_CLIP_TO_IMAGE);

  /* make sure there is only one layer, where all visible layers were merged */
  layers = gimp_image_get_layers (pipeline->rgb_image, &num_layers);
  for (i = 0; i < num_layers; i++)
    {
      if (layers[i] != pipeline->rgb_layer)
        gimp_image_remove_layer (pipeline->rgb_image, layers[i]);
    }
  g_free (layers);

  /* we don't want layer to be smaller than image */
  gimp_layer_resize_to_image_size (pipeline->rgb_layer);
  gimp_image_scale (pipeline->rgb_image,
                    pipeline->resize_width, pipeline->resize_height);
  webx_pipeline_create_background (pipeline);

  pipeline->crop_offsx *= pipeline->crop_scale_x;
  pipeline->crop_offsy *= pipeline->crop_scale_y;
  pipeline->crop_width *= pipeline->crop_scale_x;
  pipeline->crop_height *= pipeline->crop_scale_y;
  pipeline->crop_scale_x = 1.0;
  pipeline->crop_scale_y = 1.0;
  webx_pipeline_crop_clip (pipeline);

  if (pipeline->crop_width != pipeline->resize_width
      || pipeline->crop_height != pipeline->resize_height )
    {
      gimp_image_crop (pipeline->rgb_image,
                       pipeline->crop_width, pipeline->crop_height,
                       pipeline->crop_offsx, pipeline->crop_offsy);
    }
    
  if (gimp_drawable_is_indexed (pipeline->rgb_layer))
    {
      pipeline->indexed_image = gimp_image_duplicate (pipeline->rgb_image);
      gimp_image_undo_disable (pipeline->indexed_image);
      pipeline->indexed_layer =
        gimp_image_merge_visible_layers (pipeline->indexed_image,
                                         GIMP_CLIP_TO_IMAGE);
    }
  else
    {
      pipeline->indexed_image = -1;
      pipeline->indexed_layer = -1;
    }

  if ( ! gimp_drawable_is_rgb (pipeline->rgb_layer))
    gimp_image_convert_rgb (pipeline->rgb_image);

  return TRUE;
}
Exemplo n.º 2
0
/* -------------------------------------------------------
 * gap_image_set_selection_from_selection_or_drawable
 * -------------------------------------------------------
 * create a selection in the specified image_id.
 * The selection is a scaled copy of the selection in another image,
 * referred by ref_drawable_id, or a Grayscale copy of the specified ref_drawable_id
 * (in case the referred image has no selection or the flag force_from_drawable is TRUE)
 *
 *  - operates on a duplicate of the image referred by ref_drawable_id.
 *  - this duplicate is scaled to same size as specified image_id
 *
 * return TRUE in case the selection was successfully created .
 */
gboolean
gap_image_set_selection_from_selection_or_drawable(gint32 image_id, gint32 ref_drawable_id
  , gboolean force_from_drawable)
{
  gint32        l_aux_channel_id;
  gint32        ref_image_id;
  gint32        work_drawable_id;   /* the duplicate of the layer that is used as selction mask */
  gint32        dup_image_id;
  gboolean has_selection;
  gboolean non_empty;
  gint     x1, y1, x2, y2;

  if ((image_id < 0) || (ref_drawable_id < 0))
  {
    return (FALSE);
  }
  ref_image_id = gimp_item_get_image(ref_drawable_id);

  if (ref_image_id < 0)
  {
    printf("ref_drawable_id does not refer to a valid image layer_id:%d\n", (int)ref_drawable_id);
    return (FALSE);
  }



  dup_image_id = gimp_image_duplicate(ref_image_id);
  if (dup_image_id < 0)
  {
    printf("duplicating of image failed, referred souce image_id:%d\n", (int)ref_image_id);
    return (FALSE);
  }
  /* clear undo stack */
  if (gimp_image_undo_is_enabled(dup_image_id))
  {
    gimp_image_undo_disable(dup_image_id);
  }

  if ((gimp_image_width(image_id) != gimp_image_width(dup_image_id))
  ||  (gimp_image_height(image_id) != gimp_image_height(dup_image_id)))
  {
     if(gap_debug)
     {
       printf("scaling tmp image_id: %d\n", (int)dup_image_id);
     }
     gimp_image_scale(dup_image_id, gimp_image_width(image_id), gimp_image_height(image_id));
  }

  has_selection  = gimp_selection_bounds(ref_image_id, &non_empty, &x1, &y1, &x2, &y2);
  if ((has_selection) && (non_empty) && (force_from_drawable != TRUE))
  {
    /* use scaled copy of the already exisating selection in the referred image */
    work_drawable_id = gimp_image_get_selection(dup_image_id);
  }
  else
  {
    gint32        active_layer_stackposition;

    /* create selection as gray copy of the alt_selection layer */

    active_layer_stackposition = gap_layer_get_stackposition(ref_image_id, ref_drawable_id);

    if(gimp_image_base_type(dup_image_id) != GIMP_GRAY)
    {
       if(gap_debug)
       {
         printf("convert to GRAYSCALE tmp image_id: %d\n", (int)dup_image_id);
       }
       gimp_image_convert_grayscale(dup_image_id);
    }
    work_drawable_id = gap_layer_get_id_by_stackposition(dup_image_id, active_layer_stackposition);
    gimp_layer_resize_to_image_size (work_drawable_id);
  }

  gimp_selection_all(image_id);
  //l_sel_channel_id = gimp_image_get_selection(image_id);
  l_aux_channel_id = gimp_selection_save(image_id);

  /* copy the work drawable (layer or channel) into the selection channel
   * the work layer is a grayscale copy GRAY or GRAYA of the alt_selection layer
   *  that is already scaled and resized to fit the size of the target image
   * the work channel is the scaled selection of the image refred by ref_drawable_id
   *
   * copying is done into an auxiliary channel from where we regulary load the selection.
   * this is done because subseqent queries of the selection boudaries will deliver
   * full channel size rectangle after a direct copy into the selection.
   */
  gap_layer_copy_picked_channel (l_aux_channel_id  /* dst_drawable_id*/
                              , 0                  /* dst_channel_pick */
                              , work_drawable_id   /* src_drawable_id */
                              , 0                  /* src_channel_pick */
                              , FALSE              /* gboolean shadow */
                              );

  gimp_image_select_item(image_id, GIMP_CHANNEL_OP_REPLACE, l_aux_channel_id);
  gimp_image_remove_channel(image_id, l_aux_channel_id);

  gap_image_delete_immediate(dup_image_id);
  return (TRUE);

}  /* end gap_image_set_selection_from_selection_or_drawable */
Exemplo n.º 3
0
/* Compose a roll film image from several images */
static gint32
film (void)
{
  gint          width, height;
  guchar       *hole;
  gint          film_height, film_width;
  gint          picture_width, picture_height;
  gint          picture_space, picture_x0, picture_y0;
  gint          hole_offset, hole_width, hole_height, hole_space, hole_x;
  gint          number_height, num_images, num_pictures;
  gint          j, k, picture_count;
  gdouble       f;
  gint          num_layers;
  gint32       *image_ID_src, image_ID_dst, layer_ID_src, layer_ID_dst;
  gint          image_ID_tmp;
  gint32       *layers;
  GimpDrawable *drawable_dst;
  GimpPixelRgn  pixel_rgn_dst;
  gint          new_layer;
  gint          floating_sel;

  /* initialize */

  layers = NULL;

  num_images = filmvals.num_images;
  image_ID_src = filmvals.image;

  if (num_images <= 0)
    return (-1);

  gimp_context_push ();
  gimp_context_set_foreground (&filmvals.number_color);
  gimp_context_set_background (&filmvals.film_color);

  if (filmvals.keep_height) /* Search maximum picture height */
    {
      picture_height = 0;
      for (j = 0; j < num_images; j++)
        {
          height = gimp_image_height (image_ID_src[j]);
          if (height > picture_height) picture_height = height;
        }
      film_height = (int)(picture_height / filmvals.picture_height + 0.5);
      filmvals.film_height = film_height;
    }
  else
    {
      film_height = filmvals.film_height;
      picture_height = (int)(film_height * filmvals.picture_height + 0.5);
    }

  picture_space = (int)(film_height * filmvals.picture_space + 0.5);
  picture_y0 = (film_height - picture_height)/2;

  number_height = film_height * filmvals.number_height;

  /* Calculate total film width */
  film_width = 0;
  num_pictures = 0;
  for (j = 0; j < num_images; j++)
    {
      layers = gimp_image_get_layers (image_ID_src[j], &num_layers);
      /* Get scaled image size */
      width = gimp_image_width (image_ID_src[j]);
      height = gimp_image_height (image_ID_src[j]);
      f = ((double)picture_height) / (double)height;
      picture_width = width * f;

      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          film_width += (picture_space/2);  /* Leading space */
          film_width += picture_width;      /* Scaled image width */
          film_width += (picture_space/2);  /* Trailing space */
          num_pictures++;
        }

      g_free (layers);
    }

#ifdef FILM_DEBUG
  g_printerr ("film_height = %d, film_width = %d\n", film_height, film_width);
  g_printerr ("picture_height = %d, picture_space = %d, picture_y0 = %d\n",
              picture_height, picture_space, picture_y0);
  g_printerr ("Number of pictures = %d\n", num_pictures);
#endif

  image_ID_dst = create_new_image (_("Untitled"),
                                   (guint) film_width, (guint) film_height,
                                   GIMP_RGB_IMAGE, &layer_ID_dst,
                                   &drawable_dst, &pixel_rgn_dst);

  /* Fill film background */
  gimp_drawable_fill (layer_ID_dst, GIMP_FILL_BACKGROUND);

  /* Draw all the holes */
  hole_offset = film_height * filmvals.hole_offset;
  hole_width = film_height * filmvals.hole_width;
  hole_height = film_height * filmvals.hole_height;
  hole_space = film_height * filmvals.hole_space;
  hole_x = hole_space / 2;

#ifdef FILM_DEBUG
  g_printerr ("hole_x %d hole_offset %d hole_width %d hole_height %d hole_space %d\n",
              hole_x, hole_offset, hole_width, hole_height, hole_space );
#endif

  hole = create_hole_rgb (hole_width, hole_height);
  if (hole)
    {
      while (hole_x < film_width)
        {
          draw_hole_rgb (drawable_dst, hole_x,
                         hole_offset,
                         hole_width, hole_height, hole);
          draw_hole_rgb (drawable_dst, hole_x,
                         film_height-hole_offset-hole_height,
                         hole_width, hole_height, hole);

          hole_x += hole_width + hole_space;
        }
      g_free (hole);
    }
  gimp_drawable_detach (drawable_dst);


  /* Compose all images and layers */
  picture_x0 = 0;
  picture_count = 0;
  for (j = 0; j < num_images; j++)
    {
      image_ID_tmp = gimp_image_duplicate (image_ID_src[j]);
      width = gimp_image_width (image_ID_tmp);
      height = gimp_image_height (image_ID_tmp);
      f = ((gdouble) picture_height) / (gdouble) height;
      picture_width = width * f;
      if (gimp_image_base_type (image_ID_tmp) != GIMP_RGB)
        gimp_image_convert_rgb (image_ID_tmp);
      gimp_image_scale (image_ID_tmp, picture_width, picture_height);

      layers = gimp_image_get_layers (image_ID_tmp, &num_layers);
      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          picture_x0 += picture_space / 2;

          layer_ID_src = layers[k];
          gimp_layer_resize_to_image_size (layer_ID_src);
          new_layer = gimp_layer_new_from_drawable (layer_ID_src,
                                                    image_ID_dst);
          gimp_image_insert_layer (image_ID_dst, new_layer, -1, -1);
          gimp_layer_set_offsets (new_layer, picture_x0, picture_y0);

          /* Draw picture numbers */
          if ((number_height > 0) &&
              (filmvals.number_pos[0] || filmvals.number_pos[1]))
            {
              if (filmvals.number_pos[0])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             (hole_offset-number_height)/2, number_height);
              if (filmvals.number_pos[1])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             film_height - (hole_offset + number_height)/2,
                             number_height);
            }

          picture_x0 += picture_width + (picture_space/2);

          gimp_progress_update (((gdouble) (picture_count + 1)) /
                                (gdouble) num_pictures);

          picture_count++;
        }

      g_free (layers);
      gimp_image_delete (image_ID_tmp);
    }
  gimp_progress_update (1.0);

  gimp_image_flatten (image_ID_dst);

  /* Drawing text/numbers leaves us with a floating selection. Stop it */
  floating_sel = gimp_image_get_floating_sel (image_ID_dst);
  if (floating_sel != -1)
    gimp_floating_sel_anchor (floating_sel);

  gimp_context_pop ();

  return image_ID_dst;
}
Exemplo n.º 4
0
/* ------------------------------
 * gap_pview_render_f_from_image
 * ------------------------------
 * render preview widget from image.
 * IMPORTANT: the image is scaled to preview size
 *            and the visible layers in the image are merged together !
 *            If the supplied image shall stay unchanged,
 *            you may use  gap_pview_render_f_from_image_duplicate
 *
 * hint: call gtk_widget_queue_draw(pv_ptr->da_widget);
 * after this procedure to make the changes appear on screen.
 */
void
gap_pview_render_f_from_image (GapPView *pv_ptr
    , gint32 image_id
    , gint32 flip_request
    , gint32 flip_status
)
{
  gint32 layer_id;
  guchar *frame_data;
  GimpPixelRgn pixel_rgn;
  GimpDrawable *drawable;

  if(image_id < 0)
  {
    if(gap_debug)
    {
      printf("gap_pview_render_f_from_image: have no image, cant render image_id:%d\n"
            ,(int)image_id
            );
    }
    return;
  }
  p_free_desaturated_area_data(pv_ptr);

  if((gimp_image_width(image_id) != pv_ptr->pv_width)
  || ( gimp_image_height(image_id) != pv_ptr->pv_height))
  {
    gimp_image_scale(image_id, pv_ptr->pv_width, pv_ptr->pv_height);
  }

  /* workaround: gimp_image_merge_visible_layers
   * needs at least 2 layers to work without complaining
   * therefore add 2 full transparent dummy layers
   */
  {
    gint32  l_layer_id;
    GimpImageBaseType l_type;

    l_type   = gimp_image_base_type(image_id);
    l_type   = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */

    l_layer_id = gimp_layer_new(image_id, "dummy_01"
                                , 4, 4
                                , l_type
                                , 0.0       /* Opacity full transparent */     
                                , 0         /* NORMAL */
                                );   
    gimp_image_insert_layer(image_id, l_layer_id, 0, 0);

    l_layer_id = gimp_layer_new(image_id, "dummy_02"
                                , 4, 4
                                , l_type
                                , 0.0       /* Opacity full transparent */     
                                , 0         /* NORMAL */
                                );   
    gimp_image_insert_layer(image_id, l_layer_id, 0, 0);
    gimp_layer_resize_to_image_size(l_layer_id);
  }
  
    
  layer_id = gimp_image_merge_visible_layers (image_id, GIMP_CLIP_TO_IMAGE);
  drawable = gimp_drawable_get (layer_id);

  frame_data = g_malloc(drawable->width * drawable->height * drawable->bpp);
  
  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0
                      , drawable->width, drawable->height
                      , FALSE     /* dirty */
                      , FALSE     /* shadow */
                       );
  gimp_pixel_rgn_get_rect (&pixel_rgn, frame_data
                          , 0
                          , 0
                          , drawable->width
                          , drawable->height);
                          
 
 {
    gboolean frame_data_was_grabbed;

    frame_data_was_grabbed = gap_pview_render_f_from_buf (pv_ptr
                   , frame_data
                   , drawable->width
                   , drawable->height
                   , drawable->bpp
                   , TRUE            /* allow_grab_src_data */
                   , flip_request
                   , flip_status

                 );
  
    if(!frame_data_was_grabbed) g_free(frame_data);
    gimp_drawable_detach (drawable);
  }
  
}  /* end gap_pview_render_f_from_image */