Exemplo n.º 1
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 */
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
gboolean
dialog_layer_constraint_func (gint32 image_ID, gint32 layer_ID, gpointer data)
{
  gint32 ref_layer_ID = *((gint32*) data);
  if (image_ID != gimp_drawable_get_image (ref_layer_ID))
    {
      return FALSE;
    }
  if (layer_ID == ref_layer_ID)
    {
      return FALSE;
    }
  return TRUE;
}
void dialogMaskChangedCallback(GtkWidget *widget, PlugInVals *vals) {
	gint value;
#ifdef DEBUG
	g_warning("dialogMaskChangedCallback");
#endif

	if (GTK_WIDGET_SENSITIVE(widget)) {
	//if (gtk_widget_get_sensitive(widget)) {
		if (gimp_int_combo_box_get_active(GIMP_INT_COMBO_BOX(widget),&value)) {
			vals->mask_drawable_id = value;
		} else {
			vals->mask_drawable_id = -1;

		}
	} else {
		vals->mask_drawable_id = gimp_image_get_selection(gimp_drawable_get_image(vals->image_drawable_id));
	}
	update_mask(vals);
	renderPreview(vals);
}
Exemplo n.º 5
0
static gboolean
pixelize_dialog (GimpDrawable *drawable)
{
  GtkWidget *dialog;
  GtkWidget *main_vbox;
  GtkWidget *preview;
  GtkWidget *sizeentry;
  guint32    image_id;
  GimpUnit   unit;
  gdouble    xres, yres;
  gboolean   run;

  gimp_ui_init (PLUG_IN_BINARY, FALSE);

  dialog = gimp_dialog_new (_("Pixelize"), PLUG_IN_BINARY,
                            NULL, 0,
                            gimp_standard_help_func, PIXELIZE_PROC,

                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                            GTK_STOCK_OK,     GTK_RESPONSE_OK,

                            NULL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  gimp_window_set_transient (GTK_WINDOW (dialog));

  main_vbox = gtk_vbox_new (FALSE, 12);
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), main_vbox);
  gtk_widget_show (main_vbox);

  preview = gimp_drawable_preview_new (drawable, NULL);
  gtk_box_pack_start_defaults (GTK_BOX (main_vbox), preview);
  gtk_widget_show (preview);
  g_signal_connect_swapped (preview, "invalidated",
                            G_CALLBACK (pixelize),
                            drawable);

  image_id = gimp_drawable_get_image (drawable->drawable_id);
  unit = gimp_image_get_unit (image_id);
  gimp_image_get_resolution (image_id, &xres, &yres);

  sizeentry = gimp_coordinates_new (unit, "%a", TRUE, TRUE, ENTRY_WIDTH,
                                    GIMP_SIZE_ENTRY_UPDATE_SIZE,
                                    TRUE, FALSE,

                                    _("Pixel _width:"),
                                    pvals.pixelwidth, xres,
                                    1, drawable->width,
                                    1, drawable->width,

                                    _("Pixel _height:"),
                                    pvals.pixelheight, yres,
                                    1, drawable->height,
                                    1, drawable->height);

  gtk_box_pack_start (GTK_BOX (main_vbox), sizeentry, FALSE, FALSE, 0);
  gtk_widget_show (sizeentry);
  g_signal_connect (sizeentry, "value-changed",
                    G_CALLBACK (update_pixelsize),
                    preview);
  g_signal_connect (sizeentry, "refval-changed",
                    G_CALLBACK (update_pixelsize),
                    preview);

  gtk_widget_show (dialog);

  run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);

  gtk_widget_destroy (dialog);

  return run;
}
Exemplo n.º 6
0
/* -------------------------------------
 * run
 * -------------------------------------
 */
static void
run (const gchar *name,          /* name of plugin */
     gint nparams,               /* number of in-parameters */
     const GimpParam * param,    /* in-parameters */
     gint *nreturn_vals,         /* number of out-parameters */
     GimpParam ** return_vals)   /* out-parameters */
{
  const gchar *l_env;
  gint32       image_id = -1;
  gint32       drawable_id = -1;
  GapMorphGlobalParams  *mgpp = &global_params;
  gboolean      run_flag;

  /* Get the runmode from the in-parameters */
  GimpRunMode run_mode = param[0].data.d_int32;

  /* status variable, use it to check for errors in invocation usually only
   * during non-interactive calling
   */
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;

  /* always return at least the status to the caller. */
  static GimpParam values[2];

  INIT_I18N();

  l_env = g_getenv("GAP_DEBUG");
  if(l_env != NULL)
  {
    if((*l_env != 'n') && (*l_env != 'N')) gap_debug = 1;
  }

  if(gap_debug)
  {
    printf("\n\nDEBUG: run %s  RUN_MODE:%d\n", name, (int)run_mode);
  }

  run_flag = FALSE;
  if ((strcmp(name, PLUG_IN_NAME_TWEEN) == 0)
  ||  (strcmp(name, PLUG_IN_NAME_WORKPOINTS) == 0))
  {
    run_flag = TRUE;
  }
  /* initialize the return of the status */
  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;
  *nreturn_vals = 1;
  *return_vals = values;


  /* get image */
  image_id = param[1].data.d_int32;
  drawable_id = param[2].data.d_drawable;
  mgpp->do_progress = FALSE;
  mgpp->image_id = image_id;
  mgpp->run_mode = run_mode;



  switch (run_mode)
  {
    case GIMP_RUN_INTERACTIVE:
      if (strcmp(name, PLUG_IN_NAME) == 0)
      {
        /* Possibly retrieve data from a previous run */
        gimp_get_data (PLUG_IN_NAME, mgpp);
        mgpp->osrc_layer_id          = drawable_id;
        mgpp->fdst_layer_id          = gap_morph_exec_find_dst_drawable(image_id, drawable_id);
        run_flag = gap_morph_dialog(mgpp);
        mgpp->do_progress            = TRUE;
        mgpp->master_progress_callback_fptr     = NULL;
        mgpp->progress_callback_fptr            = NULL;
      }
      else if (strcmp(name, PLUG_IN_NAME_ONE_TWEEN) == 0)
      {
        mgpp->tween_mix_factor       = 0.5;
        /* Possibly retrieve data from a previous run */
        gimp_get_data (PLUG_IN_NAME_ONE_TWEEN, mgpp);
        mgpp->osrc_layer_id          = drawable_id;
        mgpp->fdst_layer_id          = gap_morph_exec_find_dst_drawable(image_id, drawable_id);
        run_flag = gap_morph_one_tween_dialog(mgpp);
        mgpp->do_progress            = TRUE;
        mgpp->master_progress_callback_fptr     = NULL;
        mgpp->progress_callback_fptr            = NULL;
      }
      /* dialog for other frame tween processing plug ins see 
       * p_handle_tween_processing_pug_ins
       */
      break;

    case GIMP_RUN_NONINTERACTIVE:
      /* check to see if invoked with the correct number of parameters */
      if ((nparams == G_N_ELEMENTS (in_args))
      && (strcmp(name, PLUG_IN_NAME) == 0))
      {
          mgpp->have_workpointsets     = TRUE;  /* use pointset(s) from file */
          
          /* set defaults for params that may be specified in the workpointfiles
           * (the defaults will take effect only if the file does not contain such settings)
           */
          mgpp->use_quality_wp_selection = FALSE;
          mgpp->use_gravity = FALSE;
          mgpp->gravity_intensity = 2.0;
          mgpp->affect_radius = 100.0;
          
          mgpp->osrc_layer_id          = param[2].data.d_drawable;
          mgpp->fdst_layer_id          = param[3].data.d_drawable;
          mgpp->tween_steps            = param[4].data.d_int32;
          mgpp->render_mode            = param[5].data.d_int32;
          mgpp->create_tween_layers    = param[6].data.d_int32;
          if(param[7].data.d_string != NULL)
          {
            if(param[7].data.d_string[0] != '\0')
            {
              g_snprintf(mgpp->workpoint_file_lower
                      , sizeof(mgpp->workpoint_file_lower)
                      , "%s", param[7].data.d_string);
              g_snprintf(mgpp->workpoint_file_upper
                      , sizeof(mgpp->workpoint_file_upper)
                      , "%s", param[7].data.d_string);
            }
            else
            {
              printf("%s: non-interactive call requires a not-empty workpoint_file_1 parameter\n"
                    , PLUG_IN_NAME
                    );
              status = GIMP_PDB_CALLING_ERROR;
            }
          }
          else
          {
            printf("%s: non-interactive call requires a not-NULL workpoint_file_1 parameter\n"
                    , PLUG_IN_NAME
                    );
            status = GIMP_PDB_CALLING_ERROR;
          }
          
          if(param[8].data.d_string != NULL)
          {
            if(param[8].data.d_string[0] != '\0')
            {
              g_snprintf(mgpp->workpoint_file_upper
                      , sizeof(mgpp->workpoint_file_upper)
                      , "%s", param[8].data.d_string);
            }
          }
          
          run_flag = TRUE;
      }
      else if ((nparams == G_N_ELEMENTS (in_one_tween_args))
      && (strcmp(name, PLUG_IN_NAME_ONE_TWEEN) == 0))
      {
          /* set defaults for params that may be specified in the workpointfiles
           * (the defaults will take effect only if the file does not contain such settings)
           */
          mgpp->use_quality_wp_selection = FALSE;
          mgpp->have_workpointsets     = FALSE;  /* operate with a single workpointfile */
          mgpp->use_gravity = FALSE;
          mgpp->gravity_intensity = 2.0;
          mgpp->affect_radius = 100.0;
          mgpp->tween_steps = 1;  /* (in this mode always render only one tween) */
          mgpp->render_mode = GAP_MORPH_RENDER_MODE_MORPH;
          mgpp->create_tween_layers = TRUE;
          
          mgpp->osrc_layer_id          = param[2].data.d_drawable;
          mgpp->fdst_layer_id          = param[3].data.d_drawable;
          mgpp->tween_mix_factor       = param[4].data.d_float;
          mgpp->do_simple_fade         = (param[5].data.d_int32 != 0);
          if(param[6].data.d_string != NULL)
          {
            if(param[6].data.d_string[0] != '\0')
            {
              g_snprintf(mgpp->workpoint_file_lower
                      , sizeof(mgpp->workpoint_file_lower)
                      , "%s", param[6].data.d_string);
              g_snprintf(mgpp->workpoint_file_upper
                      , sizeof(mgpp->workpoint_file_upper)
                      , "%s", param[6].data.d_string);
            }
            else
            {
              mgpp->have_workpointsets     = FALSE;  /* no pointset file available */
            }
            run_flag = TRUE;
          }
          else
          {
            printf("%s: non-interactive call requires a not-NULL workpoint_file parameter\n"
                    , PLUG_IN_NAME_ONE_TWEEN
                    );
            status = GIMP_PDB_CALLING_ERROR;
          }
          
          
      }
      else if ((nparams == G_N_ELEMENTS (in_one_tween_args))
      && (strcmp(name, PLUG_IN_NAME_TWEEN) == 0))
      {
          /* set defaults for params that may be specified in the workpointfiles
           * (the defaults will take effect only if the file does not contain such settings)
           */
          mgpp->use_quality_wp_selection = FALSE;
          mgpp->have_workpointsets     = FALSE;  /* operate with a single workpointfile */
          mgpp->use_gravity = FALSE;
          mgpp->gravity_intensity = 2.0;
          mgpp->affect_radius = 100.0;
          mgpp->tween_steps = 1;  /* (will be calculated later as difference of handled frame numbers) */
          mgpp->render_mode = GAP_MORPH_RENDER_MODE_MORPH;
          mgpp->create_tween_layers = TRUE;
          
          mgpp->osrc_layer_id = -1;  /* is created later as merged copy of the specified image */
          mgpp->fdst_layer_id = -1;   /* is created later as merged copy of the frame rfered by to_frame_nr parameter  */        
          mgpp->range_to = param[3].data.d_int32;
          mgpp->overwrite_flag = (param[4].data.d_int32 != 0);
          mgpp->do_simple_fade = (param[5].data.d_int32 != 0);
          mgpp->tween_mix_factor       = 1.0;  /* not relevant here */
          if(param[6].data.d_string != NULL)
          {
            if(param[6].data.d_string[0] != '\0')
            {
              g_snprintf(mgpp->workpoint_file_lower
                      , sizeof(mgpp->workpoint_file_lower)
                      , "%s", param[6].data.d_string);
              g_snprintf(mgpp->workpoint_file_upper
                      , sizeof(mgpp->workpoint_file_upper)
                      , "%s", param[6].data.d_string);
            }
            else
            {
              mgpp->have_workpointsets     = FALSE;  /* no pointset file available */
            }
            run_flag = TRUE;
          }
          else
          {
            printf("%s: non-interactive call requires a not-NULL workpoint_file parameter\n"
                    , PLUG_IN_NAME_TWEEN
                    );
            status = GIMP_PDB_CALLING_ERROR;
          }
          
      }
      else if ((nparams == G_N_ELEMENTS (in_workpoint_args))
      && (strcmp(name, PLUG_IN_NAME_WORKPOINTS) == 0))
      {
          mgpp->osrc_layer_id = -1;  /* is created later as merged copy of the specified image */
          mgpp->fdst_layer_id = -1;   /* is created later as merged copy of the frame rfered by to_frame_nr parameter  */        
          mgpp->range_to = param[3].data.d_int32;
          mgpp->numWorkpoints = param[4].data.d_int32;
          mgpp->numOutlinePoints = param[5].data.d_int32;
          mgpp->locateDetailMoveRadius = param[6].data.d_int32;
          mgpp->locateDetailShapeRadius = param[7].data.d_int32;
          mgpp->locateColordiffThreshold = param[8].data.d_float;
          mgpp->edgeColordiffThreshold = param[9].data.d_float;
          run_flag = TRUE;
      }
      else
      {
        printf("%s: non-interactive call wrong nuber %d of params were passed. (%d params are required)\n"
              , PLUG_IN_NAME
              , (int)nparams
              , (int)G_N_ELEMENTS (in_args)
              );
        status = GIMP_PDB_CALLING_ERROR;
      }
      break;

    case GIMP_RUN_WITH_LAST_VALS:
      if (strcmp(name, PLUG_IN_NAME) == 0)
      {
        /* Possibly retrieve data from a previous run */
        gimp_get_data (PLUG_IN_NAME, mgpp);
        mgpp->osrc_layer_id          = drawable_id;
        mgpp->fdst_layer_id          = gap_morph_exec_find_dst_drawable(image_id, drawable_id);
        run_flag = gap_morph_dialog(mgpp);
        mgpp->do_progress            = TRUE;
        mgpp->master_progress_callback_fptr     = NULL;
        mgpp->progress_callback_fptr            = NULL;
      }
      break;

    default:
      break;
  }

  if ((status == GIMP_PDB_SUCCESS)
  && (run_flag))
  {
    if (strcmp(name, PLUG_IN_NAME) == 0)
    {
      gap_morph_execute(mgpp);
      /* Store variable states for next run */
      if (run_mode == GIMP_RUN_INTERACTIVE)
      {
        gimp_set_data (PLUG_IN_NAME, mgpp, sizeof (GapMorphGlobalParams));
      }
    }
    else if ((strcmp(name, PLUG_IN_NAME_ONE_TWEEN) == 0) 
         || (strcmp(name, PLUG_IN_NAME_TWEEN) == 0)
         || (strcmp(name, PLUG_IN_NAME_WORKPOINTS) == 0))
    {
      gint32 tween_layer_id;
      
      if (strcmp(name, PLUG_IN_NAME_ONE_TWEEN) == 0)
      {
        tween_layer_id = gap_morph_render_one_tween(mgpp);
      }
      else
      {
        /* handle processing for PLUG_IN_NAME_TWEEN or PLUG_IN_NAME_WORKPOINTS */
        tween_layer_id = p_handle_tween_processing_pug_ins(mgpp, name);
      }


      values[1].type = GIMP_PDB_DRAWABLE;
      values[1].data.d_int32 = tween_layer_id;
      values[1].data.d_drawable = tween_layer_id;
      *nreturn_vals = 2;
      if (tween_layer_id < 0)
      {
        status = GIMP_PDB_EXECUTION_ERROR;
      }
      else
      {
         if (run_mode == GIMP_RUN_INTERACTIVE)
         {
           /* Store variable states for next run */
           gimp_set_data (name, mgpp, sizeof (GapMorphGlobalParams));
           if(strcmp(name, PLUG_IN_NAME_WORKPOINTS) != 0)
           {
             gimp_display_new(gimp_drawable_get_image(tween_layer_id));
           }
         }
      }
    }
  }

  values[0].data.d_status = status;
}       /* end run */
gboolean dialog (
	PlugInVals         *vals,
	PlugInUIVals       *ui_vals)
{
  if (!gimp_drawable_is_valid(vals->image_drawable_id)) {
	  vals->image_drawable_id = default_vals.image_drawable_id;
  }
  if (!gimp_drawable_is_valid(vals->mask_drawable_id)) {
	  vals->mask_drawable_id = default_vals.mask_drawable_id;
  }
  if (!gimp_vectors_is_valid(vals->stop_path_id)) {
	  vals->stop_path_id = default_vals.stop_path_id;
  }
  vals->output_drawable_id = vals->image_drawable_id;

  print_vals(vals);
  set_defaults(ui_vals);
  interface_vals.imageID = gimp_drawable_get_image(vals->image_drawable_id);
  interface_vals.image_name = gimp_image_get_name(interface_vals.imageID);
  interface_vals.image_drawable = NULL;
  interface_vals.mask_drawable = NULL;
  if (vals->image_drawable_id >= 0) {
#ifdef DEBUG
	  g_warning("There is an input image drawable id");
#endif
	  interface_vals.image_drawable = gimp_drawable_get(vals->image_drawable_id);
  }
  if (vals->mask_drawable_id >= 0) {
	  interface_vals.mask_drawable = gimp_drawable_get(vals->mask_drawable_id);
  } else {
	  interface_vals.mask_drawable = NULL;
  }

  ui_state = ui_vals;

  //if there is a selection create mask drawable and fill

  gimp_drawable_mask_bounds(vals->image_drawable_id,&interface_vals.selectionX0,
		  	  	  	  	  	  	  	  	  	  	  	&interface_vals.selectionY0,
		  	  	  	  	  	  	  	  	  	  	  	&interface_vals.selectionX1,
		  	  	  	  	  	  	  	  		  	  	&interface_vals.selectionY1);
  interface_vals.selectionWidth = interface_vals.selectionX1-interface_vals.selectionX0;
  interface_vals.selectionHeight = interface_vals.selectionY1-interface_vals.selectionY0;

  gint image_width = gimp_drawable_width(vals->image_drawable_id);
  gint image_height = gimp_drawable_height(vals->image_drawable_id);

  interface_vals.selectionX0 -= PREVIEW_SIZE*0.1;
  if (interface_vals.selectionX0 < 0) interface_vals.selectionX0 = 0;
  interface_vals.selectionX1 += PREVIEW_SIZE*0.1;
  if (interface_vals.selectionX1 > image_width) interface_vals.selectionX1 = image_width;
  interface_vals.selectionY0 -= PREVIEW_SIZE*0.1;
  if (interface_vals.selectionY0 < 0) interface_vals.selectionY0 = 0;
  interface_vals.selectionY1 += PREVIEW_SIZE*0.1;
  if (interface_vals.selectionY1 > image_height) interface_vals.selectionY1 = image_height;

  interface_vals.selectionWidth = interface_vals.selectionX1-interface_vals.selectionX0;
  interface_vals.selectionHeight = interface_vals.selectionY1-interface_vals.selectionY0;

  //vals->mask_drawable_id = gimp_image_get_selection(gimp_drawable_get_image(vals->image_drawable_id));
  //g_warning("there is a selection with id = %d",vals->mask_drawable_id);
  //if (interface_vals.mask_drawable != NULL) gimp_drawable_detach(interface_vals.mask_drawable);
  //interface_vals.mask_drawable = gimp_drawable_get(vals->mask_drawable_id);


#ifdef DEBUG
  g_warning("image dims: x0,x1,y0,y1 = %d,%d,%d,%d",interface_vals.selectionX0,interface_vals.selectionX1,interface_vals.selectionY0,interface_vals.selectionY1);
#endif
  gchar text[100];
  sprintf(text,"Inpainting: %s",interface_vals.image_name);

  gimp_ui_init (PLUGIN_NAME, TRUE);

  GtkWidget* dlg = gimp_dialog_new (text, PLUGIN_NAME,
                         NULL, 0,
			 gimp_standard_help_func, "gimp-inpaint-BCT",

			 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			 GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
			 GTK_STOCK_OK,     GTK_RESPONSE_OK,


			 NULL);

  gimp_window_set_transient (GTK_WINDOW (dlg));

  GtkWidget* vbox = gtk_vbox_new (FALSE, 10);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
		  vbox, FALSE, FALSE, 0);
  gtk_widget_show (vbox);

  /* Preview */
  GtkWidget* hbox = gtk_hbox_new (TRUE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  gtk_widget_show (hbox);

  GtkWidget* frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
  gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

//  interface_vals.preview = TRUE;
//  interface_vals.preview_widget = GIMP_DRAWABLE_PREVIEW (gimp_drawable_preview_new(interface_vals.image_drawable,&interface_vals.preview));
//  gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (interface_vals.preview_widget));
//  gtk_widget_show (GTK_WIDGET (interface_vals.preview_widget));

  interface_vals.previewWidth  = MIN (interface_vals.selectionWidth,  PREVIEW_SIZE);
  interface_vals.previewHeight = MIN (interface_vals.selectionHeight, PREVIEW_SIZE);
  interface_vals.preview_widget = gimp_preview_area_new ();
  gtk_widget_set_size_request (interface_vals.preview_widget,
		  interface_vals.previewWidth, interface_vals.previewHeight);
  gtk_container_add (GTK_CONTAINER (frame), interface_vals.preview_widget);
  gtk_widget_show (interface_vals.preview_widget);

  buildPreviewSourceImage (vals);


  /* Source and Mask selection */
  GtkWidget* table = gtk_table_new (5, 3, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  //gtk_table_set_row_spacing (GTK_TABLE (table), 1, 12);
  //gtk_table_set_row_spacing (GTK_TABLE (table), 3, 12);
  gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  gtk_widget_show (table);

  GtkWidget* label = gtk_label_new (_("Source:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
		  GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);

  GtkWidget* combo = gimp_drawable_combo_box_new (NULL, NULL);
#ifdef DEBUG
  g_warning("setting initi value of source combo box as %d",vals->image_drawable_id);
#endif
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), vals->image_drawable_id,
		  G_CALLBACK (dialogSourceChangedCallback),vals);

  gtk_table_attach (GTK_TABLE (table), combo, 1, 3, 0, 1,
		  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (combo);

  label = gtk_label_new(_("Mask:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
		  GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);

  interface_vals.mask_combo_widget = gimp_drawable_combo_box_new (NULL, NULL);
  if (interface_vals.mask_type == SELECTION) {
	  gtk_widget_set_sensitive(interface_vals.mask_combo_widget,FALSE);
  }
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (interface_vals.mask_combo_widget),
		  vals->mask_drawable_id,
  	  	  G_CALLBACK (dialogMaskChangedCallback),vals);


  gtk_table_attach (GTK_TABLE (table), interface_vals.mask_combo_widget, 1, 3, 1, 2,
		  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (interface_vals.mask_combo_widget);




  label = gtk_label_new (_("Stop Path:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
		  GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);

  interface_vals.stop_path_combo_widget = gimp_vectors_combo_box_new (NULL, NULL);
  gtk_widget_set_sensitive(interface_vals.stop_path_combo_widget,FALSE);
  gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (interface_vals.stop_path_combo_widget), vals->stop_path_id,
		  G_CALLBACK (dialogStopPathChangedCallback),vals);
  gtk_table_attach (GTK_TABLE (table), interface_vals.stop_path_combo_widget, 1, 3, 2, 3,
		  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (interface_vals.stop_path_combo_widget);


  label = gtk_label_new(_("Mask Type:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
		  GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);

  interface_vals.mask_type_widget = gtk_combo_box_new_text();
  gint num_vectors;
  gimp_image_get_vectors(interface_vals.imageID,&num_vectors);

  gtk_combo_box_append_text(GTK_COMBO_BOX(interface_vals.mask_type_widget),"Selection");

  if (num_vectors > 0)
	  gtk_combo_box_append_text(GTK_COMBO_BOX(interface_vals.mask_type_widget),"Selection With Stop Path");

  gtk_combo_box_append_text(GTK_COMBO_BOX(interface_vals.mask_type_widget),"Binary Mask");
  if (num_vectors > 0)
	  gtk_combo_box_append_text(GTK_COMBO_BOX(interface_vals.mask_type_widget),"Binary Mask With Stop Path");
  gtk_combo_box_append_text(GTK_COMBO_BOX(interface_vals.mask_type_widget),"Mask Including Ordering");

  if (interface_vals.mask_type == SELECTION) {
	  int mt_index = 0 + (vals->stop_path_id > 0);
	  gtk_combo_box_set_active(GTK_COMBO_BOX(interface_vals.mask_type_widget),mt_index);
  } else if (interface_vals.mask_type == BINARY_MASK) {
	  int mt_index = 1 + (num_vectors > 0) + (vals->stop_path_id > 0);
	  gtk_combo_box_set_active(GTK_COMBO_BOX(interface_vals.mask_type_widget),mt_index);
  } else {
	  int mt_index = 2 + 2*(num_vectors > 0);
	  gtk_combo_box_set_active(GTK_COMBO_BOX(interface_vals.mask_type_widget),mt_index);
  }

  g_signal_connect (interface_vals.mask_type_widget, "changed",
		  G_CALLBACK(maskTypeChangedCallback), vals);
  maskTypeChangedCallback(GTK_COMBO_BOX(interface_vals.mask_type_widget),vals);


  gtk_table_attach (GTK_TABLE (table), interface_vals.mask_type_widget, 1, 3, 3, 4,
		  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (interface_vals.mask_type_widget);

  // Create the parameter table
//  table = gtk_table_new (5, 3, FALSE);
//  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
//  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
//  gtk_container_set_border_width (GTK_CONTAINER (table), 12);
//  gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
//
//  gtk_widget_show (table);

  interface_vals.threshold_scale = gimp_scale_entry_new (GTK_TABLE (table), 0, 4,"_Mask Threshold:", SCALE_WIDTH, 0,vals->threshold, 0, 255, 0.1, 0.2, EPS_DIGITS,TRUE, 0, 0,NULL, NULL);
   g_signal_connect (interface_vals.threshold_scale, "value_changed", 	G_CALLBACK(dialogThresholdChanged), vals);

   GtkWidget *separator = gtk_hseparator_new ();
   gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 5);
   gtk_widget_show (separator);

   table = gtk_table_new (5, 3, FALSE);
   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
   gtk_table_set_row_spacings (GTK_TABLE (table), 6);
   //gtk_table_set_row_spacing (GTK_TABLE (table), 1, 12);
   //gtk_table_set_row_spacing (GTK_TABLE (table), 3, 12);
   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
   gtk_widget_show (table);


  interface_vals.epsilon_scale = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,"_Pixel neighborhood (epsilon):", SCALE_WIDTH, 0,vals->epsilon, 1, SCALE_MAX, 0.5, 0.2, EPS_DIGITS,TRUE, 0, 0,NULL, NULL);
  g_signal_connect (interface_vals.epsilon_scale, "value_changed", 	G_CALLBACK(gimp_float_adjustment_update), &vals->epsilon);

  interface_vals.kappa_scale = gimp_scale_entry_new (GTK_TABLE (table), 0, 1, "_Sharpness (kappa in %):", SCALE_WIDTH, 0,	vals->kappa, 0, CONV_MAX, 1, 0.1, KAPPA_DIGITS,TRUE, 0, 0,NULL, NULL);
  g_signal_connect (interface_vals.kappa_scale, "value_changed", 	G_CALLBACK(gimp_float_adjustment_update), &vals->kappa);

  interface_vals.sigma_scale = gimp_scale_entry_new (GTK_TABLE (table), 0, 2, "_Pre-smoothing (sigma):", SCALE_WIDTH, 0,	vals->sigma, 0, SCALE_MAX, 0.1, 0.1, SMOOTH_DIGITS,TRUE, 0, 0,NULL, NULL);
  g_signal_connect (interface_vals.sigma_scale, "value_changed", 	G_CALLBACK(gimp_float_adjustment_update), &vals->sigma);

  interface_vals.rho_scale = gimp_scale_entry_new (GTK_TABLE (table), 0, 3, "_Post-smoothing (rho):", SCALE_WIDTH, 0,	 vals->rho, 0.001, SCALE_MAX, 0.1, 0.1, SMOOTH_DIGITS,TRUE, 0, 0,NULL, NULL);
  g_signal_connect (interface_vals.rho_scale, "value_changed", 	G_CALLBACK(gimp_float_adjustment_update), &vals->rho);


//  // test extra button
//  GtkWidget *togglebutton = gtk_check_button_new_with_label("Inpaint Animation");
//  gtk_toggle_button_set_active( (GtkToggleButton *) togglebutton, ui_vals->anim_mode);
//  gtk_widget_show(togglebutton);
//
//  gimp_table_attach_aligned(GTK_TABLE (table),0,4,NULL,0,0,togglebutton,1,TRUE);
//
//  g_signal_connect (togglebutton, "toggled",	G_CALLBACK(gimp_toggle_button_update), &ui_vals->anim_mode);

  GtkWidget *default_param_button =   gtk_button_new_with_label("Default Parameters");
  gtk_widget_show(default_param_button);
  gtk_table_attach((GtkTable *)table,default_param_button,0,1,4,5,GTK_EXPAND,GTK_EXPAND,0,0);
  g_signal_connect (default_param_button, "clicked",	G_CALLBACK(set_default_param), NULL);
  //test end

  // Display dialog
  gtk_widget_show(dlg);
  renderPreview(vals);

  GtkResponseType status = gimp_dialog_run (GIMP_DIALOG (dlg));

  while (status == GTK_RESPONSE_APPLY) {
	  render (vals);
	  gimp_displays_flush ();
	  status = gimp_dialog_run (GIMP_DIALOG (dlg));
  }
  ui_vals->mask_type = interface_vals.mask_type;
  destroy();
  gtk_widget_destroy (dlg);

  return (status == GTK_RESPONSE_OK);
}
Exemplo n.º 8
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 */
Exemplo n.º 9
0
/*
 * Create new CenterFrame, and return it (GtkFrame).
 */
static GtkWidget *
nova_center_create (GimpDrawable *drawable,
                    GimpPreview  *preview)
{
  NovaCenter *center;
  GtkWidget  *frame;
  GtkWidget  *hbox;
  GtkWidget  *check;
  gint32      image_ID;
  gdouble     res_x;
  gdouble     res_y;

  center = g_new0 (NovaCenter, 1);

  center->drawable     = drawable;
  center->preview      = preview;
  center->cursor_drawn = FALSE;
  center->curx         = 0;
  center->cury         = 0;
  center->oldx         = 0;
  center->oldy         = 0;

  frame = gimp_frame_new (_("Center of Nova"));

  g_signal_connect_swapped (frame, "destroy",
                            G_CALLBACK (g_free),
                            center);

  hbox = gtk_hbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (frame), hbox);
  gtk_widget_show (hbox);

  image_ID = gimp_drawable_get_image (drawable->drawable_id);
  gimp_image_get_resolution (image_ID, &res_x, &res_y);

  center->coords = gimp_coordinates_new (GIMP_UNIT_PIXEL, "%p", TRUE, TRUE, -1,
                                         GIMP_SIZE_ENTRY_UPDATE_SIZE,
                                         FALSE, FALSE,

                                         _("_X:"), pvals.xcenter, res_x,
                                         - (gdouble) drawable->width,
                                         2 * drawable->width,
                                         0, drawable->width,

                                         _("_Y:"), pvals.ycenter, res_y,
                                         - (gdouble) drawable->height,
                                         2 * drawable->height,
                                         0, drawable->height);

  gtk_table_set_row_spacing (GTK_TABLE (center->coords), 1, 6);
  gtk_box_pack_start (GTK_BOX (hbox), center->coords, FALSE, FALSE, 0);
  gtk_widget_show (center->coords);

  g_signal_connect (center->coords, "value-changed",
                    G_CALLBACK (nova_center_coords_update),
                    center);
  g_signal_connect (center->coords, "refval-changed",
                    G_CALLBACK (nova_center_coords_update),
                    center);

  check = gtk_check_button_new_with_mnemonic (_("Show _position"));
  gtk_table_attach (GTK_TABLE (center->coords), check, 0, 5, 2, 3,
                    GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), show_cursor);
  gtk_widget_show (check);

  g_signal_connect (check, "toggled",
                    G_CALLBACK (gimp_toggle_button_update),
                    &show_cursor);
  g_signal_connect_swapped (check, "toggled",
                            G_CALLBACK (gimp_preview_invalidate),
                            preview);

  g_signal_connect (preview->area, "realize",
                    G_CALLBACK (nova_center_preview_realize),
                    center);
  g_signal_connect_after (preview->area, "expose-event",
                          G_CALLBACK (nova_center_preview_expose),
                          center);
  g_signal_connect (preview->area, "event",
                    G_CALLBACK (nova_center_preview_events),
                    center);

  nova_center_cursor_update (center);

  return frame;
}
Exemplo n.º 10
0
/* -------------------------------
 * gap_drawable_foreground_extract
 * -------------------------------
 * perform foreground extraction.
 * This is done in 3 steps INIT, EXTRACTION, DONE (e.g. cleanup)
 */
static gint32
gap_drawable_foreground_extract (GimpDrawable              *drawable,
                                 GimpDrawable              *maskDrawable,
                                 GapFgExtractValues        *fgValPtr
                                 )
{
  GappMattingState *state;
  gint32            resultLayerId;
  gint              mask_offset_x;
  gint              mask_offset_y;

  resultLayerId = -1;

  /* get mask offsets within the image
   *  - in case mask is a channel offsets are always 0)
   *  - in case mask is a layer retieve its offsets
   */
  gimp_drawable_offsets (drawable->drawable_id, &mask_offset_x, &mask_offset_y);

  state = gap_drawable_foreground_extract_matting_init (drawable,
        mask_offset_x, mask_offset_y,
        maskDrawable->width,
        maskDrawable->height
        );

  if (state)
  {
    gint32 imageId;

    imageId = gimp_drawable_get_image(drawable->drawable_id);
    resultLayerId = gimp_layer_new(imageId
            , "FG"
            , drawable->width
            , drawable->height
            , GIMP_RGBA_IMAGE
            , 100.0   /* full opacity */
            , GIMP_NORMAL_MODE       /* normal mode */
            );
    if (resultLayerId != -1)
    {
      GimpDrawable *resultDrawable;

      resultDrawable = gimp_drawable_get(resultLayerId);
      if (resultDrawable != NULL)
      {
        gint          offset_x;
        gint          offset_y;
        gboolean      resultUpdateRequired;


        resultUpdateRequired = FALSE;

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

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

        /* perform the foreground extraction */
        gap_drawable_foreground_extract_matting (maskDrawable, resultDrawable, state,
            0.0 // start_percentage 0 (non-interactive shall always start rendering immediate
            );

        /* clean up after fg extract is done */
        gap_drawable_foreground_extract_matting_done (state);

        /* postprocessing */
        if (fgValPtr->lock_color)
        {
          if(gap_debug)
          {
            printf("postprocessing: restore resultDrawable:%d RGB channels from original drawable:%d\n"
               ,(int)resultDrawable->drawable_id
               ,(int)drawable->drawable_id
               );
          }
          resultUpdateRequired = TRUE;
          gap_fg_rgn_copy_rgb_channels(drawable, resultDrawable);
        }

        if (fgValPtr->create_layermask)
        {
          gint32 resultLayerMaskId;

          /* create a new layermask (from alpha channel) */
          resultLayerMaskId = gimp_layer_create_mask(resultLayerId, GIMP_ADD_ALPHA_MASK);
          gimp_layer_add_mask(resultLayerId, resultLayerMaskId);
          if (gimp_drawable_has_alpha(drawable->drawable_id))
          {
            if(gap_debug)
            {
              printf("postprocessing: restore resultDrawable:%d ALPHA channel from original drawable:%d\n"
               ,(int)resultDrawable->drawable_id
               ,(int)drawable->drawable_id
               );
            }
            /* copy the original alpha channel to the result layer */
            gap_fg_rgn_copy_alpha_channel(drawable, resultDrawable);
            resultUpdateRequired = TRUE;
          }
        }

        if(resultUpdateRequired)
        {
          gimp_drawable_update (resultDrawable->drawable_id
                               , 0, 0
                               , resultDrawable->width, resultDrawable->height
                               );
        }


        gimp_drawable_detach (resultDrawable);
      }
    }
  }

  return (resultLayerId);

}  /* end gap_drawable_foreground_extract */
Exemplo n.º 11
0
/* --------------------------------
 * gap_moprhShapeDetectionEdgeBased
 * --------------------------------
 *
 * generates morph workpoints via edge based shape detection.
 * This is done by edge detection in the source image
 *  (specified via mgup->mgpp->osrc_layer_id)
 *
 * and picking workpoints on the detected edges
 * and locating the corresponding point in the destination image.
 *
 * IN: mgup->num_shapepoints  specifies the number of workpoints to be generated.
 */
void
gap_moprhShapeDetectionEdgeBased(GapMorphGUIParams *mgup, gboolean *cancelFlagPtr)
{
  GapMorphShapeContext  morphShapeContext;
  GapMorphShapeContext *msctx;
  gboolean deleteEdgeImage;
  GapMorphGlobalParams *mgpp;

  mgpp = mgup->mgpp;

  if(mgup->workpointGenerationBusy == TRUE)
  {
    return;
  }
  mgup->workpointGenerationBusy = TRUE;
  deleteEdgeImage = TRUE;
  
  /* init context */  
  msctx = &morphShapeContext;
  msctx->edgeColordiffThreshold = CLAMP(mgpp->edgeColordiffThreshold, 0.0, 1.0);
  msctx->locateColordiffThreshold = CLAMP(mgpp->locateColordiffThreshold, 0.0, 1.0);
  msctx->locateDetailShapeRadius = mgpp->locateDetailShapeRadius;
  msctx->locateDetailMoveRadius = mgpp->locateDetailMoveRadius;
  msctx->colorSensitivity = GAP_COLORDIFF_DEFAULT_SENSITIVITY;
  msctx->refLayerId = mgpp->osrc_layer_id;
  msctx->targetLayerId = mgpp->fdst_layer_id;
  msctx->numShapePoints = mgpp->numWorkpoints;
  msctx->countGeneratedPoints = 0;

  msctx->doProgress = TRUE;
  msctx->progressBar = mgup->progressBar;
  if(msctx->progressBar == NULL)
  {
    msctx->doProgress = FALSE;
  }
  msctx->cancelWorkpointGenerationPtr = cancelFlagPtr;

  if(gap_debug)
  {
    printf("gap_moprhShapeDetectionEdgeBased START edgeThres:%.5f  locateThres:%.5f locateRadius:%d\n"
       , (float)msctx->edgeColordiffThreshold
       , (float)msctx->locateDetailMoveRadius
       , (int)msctx->locateDetailMoveRadius
       );
  }


  msctx->edgeLayerId = gap_edgeDetection(mgup->mgpp->osrc_layer_id   /* refDrawableId */
                                 ,mgup->mgpp->edgeColordiffThreshold
                                 ,&msctx->countEdgePixels
                                 );

  msctx->edgeImageId = gimp_drawable_get_image(msctx->edgeLayerId);

  if(gap_debug)
  {
    /* show the edge image for debug purpose
     * (this image is intended for internal processing usage)
     */
    gimp_display_new(msctx->edgeImageId);
    deleteEdgeImage = FALSE;
  }
  msctx->edgeDrawable = gimp_drawable_get(msctx->edgeLayerId);

 
  if(msctx->edgeDrawable != NULL)
  {
    gint      maxWidth;
    gint      maxHeight;
    
    maxWidth = msctx->edgeDrawable->width-1;
    maxHeight = msctx->edgeDrawable->height-1;
    
    if((mgup->src_win.zoom < 1.0) && (mgup->src_win.zoom > 0.0))
    {
      gdouble   fwidth;
      gdouble   fheight;
      gint      width;
      gint      height;
      
      fwidth  = mgup->src_win.zoom * (gdouble)mgup->src_win.pv_ptr->pv_width;
      fheight = mgup->src_win.zoom * (gdouble)mgup->src_win.pv_ptr->pv_height;
      width  = CLAMP((gint)fwidth,  1, maxWidth);
      height = CLAMP((gint)fheight, 1, maxHeight);
      msctx->sel1X = CLAMP(mgup->src_win.offs_x, 0, maxWidth);
      msctx->sel1Y = CLAMP(mgup->src_win.offs_y, 0, maxHeight);
      msctx->sel2X = CLAMP((msctx->sel1X + width), 0, maxWidth);
      msctx->sel2Y = CLAMP((msctx->sel1Y + height), 0, maxHeight);
    }
    else
    {
      msctx->sel1X = 0;
      msctx->sel1Y = 0;
      msctx->sel2X = maxWidth;
      msctx->sel2Y = maxHeight;
    }
   

    if(gap_debug)
    {
      printf("Boundaries: sel1: %d / %d sel2: %d / %d  zoom:%.5f\n"
        , (int)msctx->sel1X
        , (int)msctx->sel1Y
        , (int)msctx->sel2X
        , (int)msctx->sel2Y
        , (float)mgup->src_win.zoom
        );
    }


    msctx->pftEdge = gimp_pixel_fetcher_new (msctx->edgeDrawable, FALSE /* shadow */);
    gimp_pixel_fetcher_set_edge_mode (msctx->pftEdge, GIMP_PIXEL_FETCHER_EDGE_BLACK);

    p_generateWorkpoints(msctx, mgpp);

    gimp_pixel_fetcher_destroy (msctx->pftEdge);
  }

  if(msctx->edgeDrawable != NULL)
  {
    gimp_drawable_detach(msctx->edgeDrawable);
    msctx->edgeDrawable = NULL;
  }
  
  if(deleteEdgeImage == TRUE)
  {
    gap_image_delete_immediate(msctx->edgeImageId);
  }

  if(gap_debug)
  {
    printf("gap_moprhShapeDetectionEdgeBased END\n");
  }
  mgup->workpointGenerationBusy = FALSE;
  
  return ;

}  /* end gap_moprhShapeDetectionEdgeBased */
Exemplo n.º 12
0
/* -----------------------------------------------
 * gap_morph_shape_generate_frame_tween_workpoints
 * -----------------------------------------------
 * generate workpoint files (one per frame)
 * for the specified frame range.
 * 
 */
gint32
gap_morph_shape_generate_frame_tween_workpoints(GapAnimInfo *ainfo_ptr
   , GapMorphGlobalParams *mgpp, GtkWidget *masterProgressBar, GtkWidget *progressBar, gboolean *cancelFlagPtr)
{
  GapMorphGUIParams morph_gui_params;
  GapMorphGUIParams *mgup;
  gint32 frameCount;
  gint32 currFrameNr;
  gint32 nextFrameNr;
  gint32 currLayerId;
  gint32 nextLayerId;
  gint32 firstFrameNr;
  gint32 lastFrameNr;
  gdouble framesToProcess;
  

  mgup = &morph_gui_params;
  mgup->mgpp = mgpp;
  mgup->src_win.zoom = 1.0;  /* no zoom available here (use full drawable size for workpoint generation */
  mgup->cancelWorkpointGeneration = FALSE;
  mgup->progressBar = progressBar;  
  mgpp->master_wp_list = NULL;

  gimp_rgb_set(&mgup->pointcolor, 0.1, 1.0, 0.1); /* startup with GREEN pointcolor */
  gimp_rgb_set_alpha(&mgup->pointcolor, 1.0);
  gimp_rgb_set(&mgup->curr_pointcolor, 1.0, 1.0, 0.1); /* startup with YELLOW color */
  gimp_rgb_set_alpha(&mgup->curr_pointcolor, 1.0);

  frameCount = 0;
  nextLayerId = -1;
 
  if(gap_lib_chk_framerange(ainfo_ptr) != 0)
  {
    return(0);
  }

  
  firstFrameNr = CLAMP(mgpp->range_from, ainfo_ptr->first_frame_nr, ainfo_ptr->last_frame_nr);
  currFrameNr = firstFrameNr;
  currLayerId = p_getMergedFrameImageLayer(ainfo_ptr, currFrameNr);
  nextFrameNr = currFrameNr + 1;
  while(TRUE)
  {
    lastFrameNr = MIN(mgpp->range_to, ainfo_ptr->last_frame_nr);
    framesToProcess = MAX(1, (lastFrameNr - currFrameNr) -1);
    
    if (nextFrameNr > lastFrameNr)
    {
      break;
    }
    nextLayerId = p_getMergedFrameImageLayer(ainfo_ptr, nextFrameNr);
    
    if((nextLayerId >= 0) && (currLayerId >= 0))
    {
      char *workpointFileName;
      gboolean success;

      workpointFileName = gap_lib_alloc_fname(ainfo_ptr->basename,
                                      currFrameNr,
                                      "." GAP_MORPH_WORKPOINT_EXTENSION);      

      p_do_master_progress(masterProgressBar
                          , workpointFileName
                          , framesToProcess
                          , (currFrameNr - firstFrameNr)
                          );
   
      success = p_generateWorkpointFileForFramePair(workpointFileName
                              , mgup
                              , cancelFlagPtr
                              , currLayerId
                              , nextLayerId
                              );

      g_free(workpointFileName);
      gap_image_delete_immediate(gimp_drawable_get_image(currLayerId));
      if(!success)
      {
        break;
      }

      currFrameNr = nextFrameNr;
      currLayerId = nextLayerId;
    }
    nextFrameNr++;

  }
  
  if(nextLayerId >= 0)
  {
    gap_image_delete_immediate(gimp_drawable_get_image(nextLayerId));
  }

  return (frameCount);
}  /* end gap_morph_shape_generate_frame_tween_workpoints */