示例#1
0
/* The main rotate function */
static void
rotate (void)
{
  GimpDrawable *drawable;
  gint32       *layers;
  gint          i;
  gint          nlayers;
  gint32        guide_ID;
  GuideInfo    *guide;
  GList        *guides = NULL;
  GList        *list;

  if (rotvals.angle == 0) return;

  /* if there's a selection and we try to rotate the whole image */
  /* create an error message and exit                            */
  if (rotvals.everything)
    {
      if (! gimp_selection_is_empty (image_ID))
        {
          gimp_message (_("You can not rotate the whole image if there's a selection."));
          gimp_drawable_detach (active_drawable);
          return;
        }
      if (gimp_item_is_layer (active_drawable->drawable_id) &&
          gimp_layer_is_floating_sel (active_drawable->drawable_id))
        {
          gimp_message (_("You can not rotate the whole image if there's a floating selection."));
          gimp_drawable_detach (active_drawable);
          return;
        }
    }
  else
    /* if we are trying to rotate a channel or a mask,
       create an error message and exit */
    {
      if (! gimp_item_is_layer (active_drawable->drawable_id))
        {
          gimp_message (_("Sorry, channels and masks can not be rotated."));
          gimp_drawable_detach (active_drawable);
          return;
        }
    }

  gimp_progress_init (_("Rotating"));

  gimp_image_undo_group_start (image_ID);

  if (rotvals.everything)  /* rotate the whole image */
    {
      gint32 width = gimp_image_width (image_ID);
      gint32 height = gimp_image_height (image_ID);

      gimp_drawable_detach (active_drawable);
      layers = gimp_image_get_layers (image_ID, &nlayers);
      for (i = 0; i < nlayers; i++)
        {
          drawable = gimp_drawable_get (layers[i]);
          rotate_drawable (drawable);
          gimp_drawable_detach (drawable);
        }
      g_free (layers);

      /* build a list of all guides and remove them */
      guide_ID = 0;
      while ((guide_ID = gimp_image_find_next_guide (image_ID, guide_ID)) != 0)
        {
          guide = g_new (GuideInfo, 1);
          guide->ID = guide_ID;
          guide->orientation = gimp_image_get_guide_orientation (image_ID,
                                                                 guide_ID);
          guide->position = gimp_image_get_guide_position (image_ID, guide_ID);
          guides = g_list_prepend (guides, guide);
        }
      for (list = guides; list; list = list->next)
        {
          guide = (GuideInfo *) list->data;
          gimp_image_delete_guide (image_ID, guide->ID);
        }

      /* if rotation is not 180 degrees, resize the image */
      /*    Do it now after the guides are removed, since */
      /*    gimp_image_resize() moves the guides.         */
      if (rotvals.angle != 2)
        gimp_image_resize (image_ID, height, width, 0, 0);

      /* add the guides back to the image */
      if (guides)
        {
          switch (rotvals.angle)
            {
            case 1:
              for (list = guides; list; list = list->next)
                {
                  guide = (GuideInfo *)list->data;
                  if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
                    gimp_image_add_vguide (image_ID, height - guide->position);
                  else
                    gimp_image_add_hguide (image_ID, guide->position);
                  g_free (guide);
                }
              break;
            case 2:
              for (list = guides; list; list = list->next)
                {
                  guide = (GuideInfo *)list->data;
                  if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
                    gimp_image_add_hguide (image_ID, height - guide->position);
                  else
                    gimp_image_add_vguide (image_ID, width - guide->position);
                  g_free (guide);
                }
              break;
            case 3:
              for (list = guides; list; list = list->next)
                {
                  guide = (GuideInfo *)list->data;
                  if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
                    gimp_image_add_vguide (image_ID, guide->position);
                  else
                    gimp_image_add_hguide (image_ID, width - guide->position);
                  g_free (guide);
                }
              break;
            default:
              break;
            }
          g_list_free (guides);
        }
    }
  else  /* rotate only the active layer */
    {

      /* check for active selection and float it */
      if (! gimp_selection_is_empty (image_ID) &&
          ! gimp_layer_is_floating_sel (active_drawable->drawable_id))
        {
          active_drawable =
            gimp_drawable_get (gimp_selection_float (image_ID,
                                                     active_drawable->drawable_id,
                                                     0, 0));
        }

      rotate_drawable (active_drawable);
      gimp_drawable_detach (active_drawable);
    }

  gimp_image_undo_group_end (image_ID);

  return;
}
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[1];
  gint32             image_ID;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status    = GIMP_PDB_SUCCESS;
  gboolean           no_dialog;

  INIT_I18N ();
  gegl_init (NULL, NULL);

  run_mode = param[0].data.d_int32;

  no_dialog = (strcmp (name, "plug-in-sel2path") == 0);

  *nreturn_vals = 1;
  *return_vals = values;

  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;

  image_ID = param[1].data.d_image;
  if (image_ID < 0)
    {
      g_warning ("plug-in-sel2path needs a valid image ID");
      return;
    }

  if (gimp_selection_is_empty (image_ID))
    {
      g_message (_("No selection to convert"));
      return;
    }

  fit_set_default_params (&selVals);

  if (!no_dialog)
    {
      switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
          if (gimp_get_data_size ("plug-in-sel2path-advanced") > 0)
            {
              gimp_get_data ("plug-in-sel2path-advanced", &selVals);
            }

          if (!sel2path_dialog (&selVals))
            return;

          /* Get the current settings */
          fit_set_params (&selVals);
          break;

        case GIMP_RUN_NONINTERACTIVE:
          if (nparams != 23)
            status = GIMP_PDB_CALLING_ERROR;

          if (status == GIMP_PDB_SUCCESS)
            {
              selVals.align_threshold             =  param[3].data.d_float;
              selVals.corner_always_threshold     =  param[4].data.d_float;
              selVals.corner_surround             =  param[5].data.d_int8;
              selVals.corner_threshold            =  param[6].data.d_float;
              selVals.error_threshold             =  param[7].data.d_float;
              selVals.filter_alternative_surround =  param[8].data.d_int8;
              selVals.filter_epsilon              =  param[9].data.d_float;
              selVals.filter_iteration_count      = param[10].data.d_int8;
              selVals.filter_percent              = param[11].data.d_float;
              selVals.filter_secondary_surround   = param[12].data.d_int8;
              selVals.filter_surround             = param[13].data.d_int8;
              selVals.keep_knees                  = param[14].data.d_int8;
              selVals.line_reversion_threshold    = param[15].data.d_float;
              selVals.line_threshold              = param[16].data.d_float;
              selVals.reparameterize_improvement  = param[17].data.d_float;
              selVals.reparameterize_threshold    = param[18].data.d_float;
              selVals.subdivide_search            = param[19].data.d_float;
              selVals.subdivide_surround          = param[20].data.d_int8;
              selVals.subdivide_threshold         = param[21].data.d_float;
              selVals.tangent_surround            = param[22].data.d_int8;
              fit_set_params (&selVals);
            }
          break;

        case GIMP_RUN_WITH_LAST_VALS:
          if(gimp_get_data_size ("plug-in-sel2path-advanced") > 0)
            {
              gimp_get_data ("plug-in-sel2path-advanced", &selVals);

              /* Set up the last values */
              fit_set_params (&selVals);
            }
          break;

        default:
          break;
        }
    }

  sel2path (image_ID);
  values[0].data.d_status = status;

  if (status == GIMP_PDB_SUCCESS)
    {
      dialog_print_selVals(&selVals);
      if (run_mode == GIMP_RUN_INTERACTIVE && !no_dialog)
        gimp_set_data ("plug-in-sel2path-advanced", &selVals, sizeof(SELVALS));
    }
}
示例#3
0
文件: lcms.c 项目: WilfR/Gimp-Matting
static gboolean
lcms_image_apply_profile (gint32                    image,
                          cmsHPROFILE               src_profile,
                          cmsHPROFILE               dest_profile,
                          const gchar              *filename,
                          GimpColorRenderingIntent  intent,
                          gboolean                  bpc)
{
  gint32 saved_selection = -1;

  gimp_image_undo_group_start (image);

  if (! lcms_image_set_profile (image, dest_profile, filename, FALSE))
    {
      gimp_image_undo_group_end (image);

      return FALSE;
    }

  {
    gchar  *src  = lcms_icc_profile_get_desc (src_profile);
    gchar  *dest = lcms_icc_profile_get_desc (dest_profile);

      /* ICC color profile conversion */
      gimp_progress_init_printf (_("Converting from '%s' to '%s'"), src, dest);

      g_printerr ("lcms: converting from '%s' to '%s'\n", src, dest);

      g_free (dest);
      g_free (src);
  }

  if (! gimp_selection_is_empty (image))
    {
      saved_selection = gimp_selection_save (image);
      gimp_selection_none (image);
    }

  switch (gimp_image_base_type (image))
    {
    case GIMP_RGB:
      lcms_image_transform_rgb (image,
                                src_profile, dest_profile, intent, bpc);
      break;

    case GIMP_GRAY:
      g_warning ("colorspace conversion not implemented for "
                 "grayscale images");
      break;

    case GIMP_INDEXED:
      lcms_image_transform_indexed (image,
                                    src_profile, dest_profile, intent, bpc);
      break;
    }

  if (saved_selection != -1)
    {
      gimp_image_select_item (image, GIMP_CHANNEL_OP_REPLACE, saved_selection);
      gimp_image_remove_channel (image, saved_selection);
    }

  gimp_progress_update (1.0);

  gimp_image_undo_group_end (image);

  return TRUE;
}
示例#4
0
/* --------------------------------------------
 * gap_fg_from_selection_exec_apply_run
 * --------------------------------------------
 * generate a tri map from the current selection by filling the shrinked
 * shape with white, the expanded shape with black and the borderline
 * between shrinked and expanded selection with medium gray.
 * the trimap is attached as layermask to the input drawable,
 * and used as input for the foreground selection via alpha matting algorithm,
 * that creates a resulting layer with trimmed selection.
 *
 */
gint
gap_fg_from_selection_exec_apply_run (gint32 image_id, gint32 drawable_id
                             , gboolean doProgress, gboolean doFlush
                             , GapFgSelectValues *fsValPtr)
{
  GimpRGB   color;
  gint32    activeSelection;
  gint32    shrinkedSelection;
  gint32    trimap;
  gboolean  hadSelection;
  gint      rc;

  rc = 0;
  trimap = -1;
  activeSelection = -1;
  shrinkedSelection = -1;
  hadSelection = FALSE;
  
  gimp_context_push();
  gimp_image_undo_group_start(image_id);
  

  if (gimp_selection_is_empty(image_id) == TRUE)
  {
     if (gimp_drawable_has_alpha(drawable_id) == FALSE)
     {
       /* if the layer has no alpha select all */
       gimp_selection_all(image_id);
     }
     else
     {
       gimp_selection_layer_alpha(drawable_id);
     }
     activeSelection = gimp_selection_save(image_id);
  }
  else
  {
    activeSelection = gimp_selection_save(image_id);
    hadSelection = TRUE;
  }


  trimap = gimp_layer_get_mask(drawable_id);
  if (trimap < 0)
  {
    /* create trimap as new layermask */
    trimap = gimp_layer_create_mask(drawable_id, GIMP_ADD_BLACK_MASK);
    gimp_layer_add_mask(drawable_id, trimap);
  }
  else
  {
    /* use BLACK color to fill the already existing layermask
     * (note that gimp_drawable_fill is used to fill the entire mask
     * regardless to the current selection)
     */
    color.r = 0.0;
    color.g = 0.0;
    color.b = 0.0;
    color.a = 1.0;
    gimp_context_set_background (&color);
    gimp_drawable_fill(trimap, GIMP_BACKGROUND_FILL);
  }
  
  gimp_selection_sharpen(image_id);
  if (fsValPtr->innerRadius > 0)
  {
    gimp_selection_shrink(image_id, fsValPtr->innerRadius);
  }
  shrinkedSelection = gimp_selection_save(image_id);
  
  
  /* use WHITE color to mark foreground regions
   */
  color.r = 1.0;
  color.g = 1.0;
  color.b = 1.0;
  color.a = 1.0;
  gimp_context_set_background (&color);
  gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL);
  
  gimp_selection_load(activeSelection);
  gimp_selection_sharpen(image_id);
  if (fsValPtr->outerRadius > 0)
  {
    gimp_selection_grow(image_id, fsValPtr->outerRadius);
  }
  gimp_selection_combine(shrinkedSelection, GIMP_CHANNEL_OP_SUBTRACT);

  /* use medium GRAY to mark undefined regions
   */
  color.r = 0.5;
  color.g = 0.5;
  color.b = 0.5;
  color.a = 1.0;
  gimp_context_set_background (&color);
  gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL);

  gimp_selection_none(image_id);

  /* perform the foreground selection (that creates the resulting layer) */
  {
    GapFgExtractValues fgExtractValues;
    GapFgExtractValues *fgValPtr;
    
    fgValPtr = &fgExtractValues;
    fgValPtr->input_drawable_id = drawable_id;
    fgValPtr->tri_map_drawable_id = trimap;
    fgValPtr->create_result = TRUE;
    fgValPtr->create_layermask = fsValPtr->create_layermask;
    fgValPtr->lock_color = fsValPtr->lock_color;
    fgValPtr->colordiff_threshold = fsValPtr->colordiff_threshold;

    rc = gap_fg_matting_exec_apply_run (image_id, drawable_id
                                 , doProgress, doFlush
                                 , fgValPtr
                                 );
  }
  
  
  /* restore original selection */
  if (hadSelection == TRUE)
  {
    gimp_selection_load(activeSelection);
  }

  gimp_image_undo_group_end(image_id);
  gimp_context_pop();
  
  return (rc);

}  /* end gap_fg_from_selection_exec_apply_run */
示例#5
0
/* do the analyzing */
static void
analyze (GimpDrawable *drawable)
{
  GimpPixelRgn  srcPR;
  guchar       *src_row, *cmap;
  gint          x, y, numcol;
  gint          x1, y1, x2, y2;
  guchar        r, g, b;
  gint          a;
  guchar        idx;
  gboolean      gray;
  gboolean      has_alpha;
  gboolean      has_sel;
  guchar       *sel;
  GimpPixelRgn  selPR;
  gint          ofsx, ofsy;
  GimpDrawable *selDrawable;

  gimp_progress_init (_("Colorcube Analysis"));

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  /*
   * Get the size of the input image (this will/must be the same
   * as the size of the output image).
   */
  width = drawable->width;
  height = drawable->height;
  bpp = drawable->bpp;

  has_sel = !gimp_selection_is_empty (imageID);
  gimp_drawable_offsets (drawable->drawable_id, &ofsx, &ofsy);

  /* initialize the pixel region */
  gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);

  cmap = gimp_image_get_colormap (imageID, &numcol);
  gray = (gimp_drawable_is_gray (drawable->drawable_id) ||
          gimp_item_is_channel (drawable->drawable_id));
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  selDrawable = gimp_drawable_get (gimp_image_get_selection (imageID));
  gimp_pixel_rgn_init (&selPR,
                       selDrawable,
                       0, 0, width, height, FALSE, FALSE);

  /* allocate row buffer */
  src_row = g_new (guchar, (x2 - x1) * bpp);
  sel = g_new (guchar, x2 - x1);

  for (y = y1; y < y2; y++)
    {
      gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y, (x2 - x1));
      if (has_sel)
        gimp_pixel_rgn_get_row (&selPR, sel, x1 + ofsx, y + ofsy, (x2 - x1));

      for (x = 0; x < x2 - x1; x++)
        {
          /* Start with full opacity.  */
          a = 255;

          /*
           * If the image is indexed, fetch RGB values
           * from colormap.
           */
          if (cmap)
            {
              idx = src_row[x * bpp];

              r = cmap[idx * 3];
              g = cmap[idx * 3 + 1];
              b = cmap[idx * 3 + 2];
              if (has_alpha)
                a = src_row[x * bpp + 1];
            }
          else if (gray)
            {
              r = g = b = src_row[x * bpp];
              if (has_alpha)
                a = src_row[x * bpp + 1];
            }
          else
            {
              r = src_row[x * bpp];
              g = src_row[x * bpp + 1];
              b = src_row[x * bpp + 2];
              if (has_alpha)
                a = src_row[x * bpp + 3];
            }

          if (has_sel)
            a *= sel[x];
          else
            a *= 255;

          if (a != 0)
            insertcolor (r, g, b, (gdouble) a * (1.0 / (255.0 * 255.0)));
        }

      /* tell the user what we're doing */
      if ((y % 10) == 0)
        gimp_progress_update ((gdouble) y / (gdouble) (y2 - y1));
    }

  gimp_progress_update (1.0);

  /* clean up */
  gimp_drawable_detach (selDrawable);
  g_free (src_row);
  g_free (sel);
}