mirror of https://github.com/GNOME/gimp.git
app: implement converting images between precisions, including menu items
This commit is contained in:
parent
17e36e9b3f
commit
b4580e74e6
|
@ -54,6 +54,7 @@ static const GimpActionEntry image_actions[] =
|
|||
|
||||
{ "image-menu", NULL, NC_("image-action", "_Image") },
|
||||
{ "image-mode-menu", NULL, NC_("image-action", "_Mode") },
|
||||
{ "image-precision-menu", NULL, NC_("image-action", "_Precision") },
|
||||
{ "image-transform-menu", NULL, NC_("image-action", "_Transform") },
|
||||
{ "image-guides-menu", NULL, NC_("image-action", "_Guides") },
|
||||
|
||||
|
@ -136,7 +137,7 @@ static const GimpActionEntry image_actions[] =
|
|||
GIMP_HELP_IMAGE_PROPERTIES }
|
||||
};
|
||||
|
||||
static const GimpRadioActionEntry image_convert_actions[] =
|
||||
static const GimpRadioActionEntry image_convert_base_type_actions[] =
|
||||
{
|
||||
{ "image-convert-rgb", GIMP_STOCK_CONVERT_RGB,
|
||||
NC_("image-convert-action", "_RGB"), NULL,
|
||||
|
@ -154,6 +155,24 @@ static const GimpRadioActionEntry image_convert_actions[] =
|
|||
GIMP_INDEXED, GIMP_HELP_IMAGE_CONVERT_INDEXED }
|
||||
};
|
||||
|
||||
static const GimpRadioActionEntry image_convert_precision_actions[] =
|
||||
{
|
||||
{ "image-convert-u8", NULL,
|
||||
NC_("image-convert-action", "8 bit unsigned integer"), NULL,
|
||||
NC_("image-convert-action", "Convert the image to 8 bit unsigned integer"),
|
||||
GIMP_PRECISION_U8, GIMP_HELP_IMAGE_CONVERT_U8 },
|
||||
|
||||
{ "image-convert-u16", NULL,
|
||||
NC_("image-convert-action", "16 bit unsigned integer"), NULL,
|
||||
NC_("image-convert-action", "Convert the image to 16 bit unsigned integer"),
|
||||
GIMP_PRECISION_U16, GIMP_HELP_IMAGE_CONVERT_U16 },
|
||||
|
||||
{ "image-convert-float", NULL,
|
||||
NC_("image-convert-action", "16 bit floating point"), NULL,
|
||||
NC_("image-convert-action", "Convert the image to 16 bit floating point"),
|
||||
GIMP_PRECISION_FLOAT, GIMP_HELP_IMAGE_CONVERT_FLOAT }
|
||||
};
|
||||
|
||||
static const GimpEnumActionEntry image_flip_actions[] =
|
||||
{
|
||||
{ "image-flip-horizontal", GIMP_STOCK_FLIP_HORIZONTAL,
|
||||
|
@ -199,10 +218,16 @@ image_actions_setup (GimpActionGroup *group)
|
|||
G_N_ELEMENTS (image_actions));
|
||||
|
||||
gimp_action_group_add_radio_actions (group, "image-convert-action",
|
||||
image_convert_actions,
|
||||
G_N_ELEMENTS (image_convert_actions),
|
||||
image_convert_base_type_actions,
|
||||
G_N_ELEMENTS (image_convert_base_type_actions),
|
||||
NULL, 0,
|
||||
G_CALLBACK (image_convert_cmd_callback));
|
||||
G_CALLBACK (image_convert_base_type_cmd_callback));
|
||||
|
||||
gimp_action_group_add_radio_actions (group, "image-convert-action",
|
||||
image_convert_precision_actions,
|
||||
G_N_ELEMENTS (image_convert_precision_actions),
|
||||
NULL, 0,
|
||||
G_CALLBACK (image_convert_precision_cmd_callback));
|
||||
|
||||
gimp_action_group_add_enum_actions (group, "image-action",
|
||||
image_flip_actions,
|
||||
|
@ -229,6 +254,7 @@ image_actions_update (GimpActionGroup *group,
|
|||
gpointer data)
|
||||
{
|
||||
GimpImage *image = action_data_get_image (data);
|
||||
gboolean is_indexed = FALSE;
|
||||
gboolean is_u8 = FALSE;
|
||||
gboolean aux = FALSE;
|
||||
gboolean lp = FALSE;
|
||||
|
@ -242,21 +268,25 @@ image_actions_update (GimpActionGroup *group,
|
|||
|
||||
switch (gimp_image_base_type (image))
|
||||
{
|
||||
case GIMP_RGB:
|
||||
action = "image-convert-rgb";
|
||||
break;
|
||||
|
||||
case GIMP_GRAY:
|
||||
action = "image-convert-grayscale";
|
||||
break;
|
||||
|
||||
case GIMP_INDEXED:
|
||||
action = "image-convert-indexed";
|
||||
case GIMP_RGB: action = "image-convert-rgb"; break;
|
||||
case GIMP_GRAY: action = "image-convert-grayscale"; break;
|
||||
case GIMP_INDEXED: action = "image-convert-indexed"; break;
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_action_group_set_action_active (group, action, TRUE);
|
||||
|
||||
switch (gimp_image_get_precision (image))
|
||||
{
|
||||
case GIMP_PRECISION_U8: action = "image-convert-u8"; break;
|
||||
case GIMP_PRECISION_U16: action = "image-convert-u16"; break;
|
||||
case GIMP_PRECISION_FLOAT: action = "image-convert-float"; break;
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_action_group_set_action_active (group, action, TRUE);
|
||||
|
||||
is_indexed = (gimp_image_base_type (image) == GIMP_INDEXED);
|
||||
is_u8 = (gimp_image_get_precision (image) == GIMP_PRECISION_U8);
|
||||
aux = (gimp_image_get_active_channel (image) != NULL);
|
||||
lp = ! gimp_image_is_empty (image);
|
||||
|
@ -274,6 +304,10 @@ image_actions_update (GimpActionGroup *group,
|
|||
SET_SENSITIVE ("image-convert-grayscale", image);
|
||||
SET_SENSITIVE ("image-convert-indexed", image && !groups && is_u8);
|
||||
|
||||
SET_SENSITIVE ("image-convert-u8", image);
|
||||
SET_SENSITIVE ("image-convert-u16", image && !is_indexed);
|
||||
SET_SENSITIVE ("image-convert-float", image && !is_indexed);
|
||||
|
||||
SET_SENSITIVE ("image-flip-horizontal", image);
|
||||
SET_SENSITIVE ("image-flip-vertical", image);
|
||||
SET_SENSITIVE ("image-rotate-90", image);
|
||||
|
|
|
@ -149,7 +149,7 @@ image_convert_dialog_unset (GtkWidget *widget)
|
|||
}
|
||||
|
||||
void
|
||||
image_convert_cmd_callback (GtkAction *action,
|
||||
image_convert_base_type_cmd_callback (GtkAction *action,
|
||||
GtkAction *current,
|
||||
gpointer data)
|
||||
{
|
||||
|
@ -211,6 +211,26 @@ image_convert_cmd_callback (GtkAction *action,
|
|||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
image_convert_precision_cmd_callback (GtkAction *action,
|
||||
GtkAction *current,
|
||||
gpointer data)
|
||||
{
|
||||
GimpImage *image;
|
||||
GimpDisplay *display;
|
||||
GimpPrecision value;
|
||||
return_if_no_image (image, data);
|
||||
return_if_no_display (display, data);
|
||||
|
||||
value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
|
||||
|
||||
if (value == gimp_image_get_precision (image))
|
||||
return;
|
||||
|
||||
gimp_image_convert_precision (image, value, GIMP_PROGRESS (display));
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
void
|
||||
image_resize_cmd_callback (GtkAction *action,
|
||||
gpointer data)
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
void image_new_cmd_callback (GtkAction *action,
|
||||
gpointer data);
|
||||
|
||||
void image_convert_cmd_callback (GtkAction *action,
|
||||
void image_convert_base_type_cmd_callback (GtkAction *action,
|
||||
GtkAction *current,
|
||||
gpointer data);
|
||||
void image_convert_precision_cmd_callback (GtkAction *action,
|
||||
GtkAction *current,
|
||||
gpointer data);
|
||||
|
||||
|
|
|
@ -1027,6 +1027,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_GROUP_VECTORS_IMPORT, "GIMP_UNDO_GROUP_VECTORS_IMPORT", "group-vectors-import" },
|
||||
{ GIMP_UNDO_GROUP_MISC, "GIMP_UNDO_GROUP_MISC", "group-misc" },
|
||||
{ GIMP_UNDO_IMAGE_TYPE, "GIMP_UNDO_IMAGE_TYPE", "image-type" },
|
||||
{ GIMP_UNDO_IMAGE_PRECISION, "GIMP_UNDO_IMAGE_PRECISION", "image-precision" },
|
||||
{ GIMP_UNDO_IMAGE_SIZE, "GIMP_UNDO_IMAGE_SIZE", "image-size" },
|
||||
{ GIMP_UNDO_IMAGE_RESOLUTION, "GIMP_UNDO_IMAGE_RESOLUTION", "image-resolution" },
|
||||
{ GIMP_UNDO_IMAGE_GRID, "GIMP_UNDO_IMAGE_GRID", "image-grid" },
|
||||
|
@ -1113,6 +1114,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_GROUP_VECTORS_IMPORT, NC_("undo-type", "Import paths"), NULL },
|
||||
{ GIMP_UNDO_GROUP_MISC, NC_("undo-type", "Plug-In"), NULL },
|
||||
{ GIMP_UNDO_IMAGE_TYPE, NC_("undo-type", "Image type"), NULL },
|
||||
{ GIMP_UNDO_IMAGE_PRECISION, NC_("undo-type", "Image precision"), NULL },
|
||||
{ GIMP_UNDO_IMAGE_SIZE, NC_("undo-type", "Image size"), NULL },
|
||||
{ GIMP_UNDO_IMAGE_RESOLUTION, NC_("undo-type", "Image resolution change"), NULL },
|
||||
{ GIMP_UNDO_IMAGE_GRID, NC_("undo-type", "Grid"), NULL },
|
||||
|
|
|
@ -487,6 +487,7 @@ typedef enum /*< pdb-skip >*/
|
|||
/* Undo types which actually do something */
|
||||
|
||||
GIMP_UNDO_IMAGE_TYPE, /*< desc="Image type" >*/
|
||||
GIMP_UNDO_IMAGE_PRECISION, /*< desc="Image precision" >*/
|
||||
GIMP_UNDO_IMAGE_SIZE, /*< desc="Image size" >*/
|
||||
GIMP_UNDO_IMAGE_RESOLUTION, /*< desc="Image resolution change" >*/
|
||||
GIMP_UNDO_IMAGE_GRID, /*< desc="Grid" >*/
|
||||
|
|
|
@ -1085,6 +1085,79 @@ gimp_image_convert (GimpImage *image,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_convert_precision (GimpImage *image,
|
||||
GimpPrecision precision,
|
||||
GimpProgress *progress)
|
||||
{
|
||||
GList *all_drawables;
|
||||
GList *list;
|
||||
const gchar *undo_desc = NULL;
|
||||
gint nth_drawable, n_drawables;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (image));
|
||||
g_return_if_fail (precision != gimp_image_get_precision (image));
|
||||
g_return_if_fail (precision == GIMP_PRECISION_U8 ||
|
||||
gimp_image_base_type (image) != GIMP_INDEXED);
|
||||
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
|
||||
|
||||
all_drawables = g_list_concat (gimp_image_get_layer_list (image),
|
||||
gimp_image_get_channel_list (image));
|
||||
|
||||
n_drawables = g_list_length (all_drawables);
|
||||
|
||||
switch (precision)
|
||||
{
|
||||
case GIMP_PRECISION_U8:
|
||||
undo_desc = C_("undo-type", "Convert Image to 8 bit unsigned integer");
|
||||
break;
|
||||
|
||||
case GIMP_PRECISION_U16:
|
||||
undo_desc = C_("undo-type", "Convert Image to 16 bit unsigned integer");
|
||||
break;
|
||||
|
||||
case GIMP_PRECISION_FLOAT:
|
||||
undo_desc = C_("undo-type", "Convert Image to 32 bit float");
|
||||
break;
|
||||
}
|
||||
|
||||
if (progress)
|
||||
gimp_progress_start (progress, undo_desc, FALSE);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (image));
|
||||
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
|
||||
undo_desc);
|
||||
|
||||
/* Push the image type to the stack */
|
||||
gimp_image_undo_push_image_precision (image, NULL);
|
||||
|
||||
/* Set the new precision */
|
||||
g_object_set (image, "precision", precision, NULL);
|
||||
|
||||
for (list = all_drawables, nth_drawable = 0;
|
||||
list;
|
||||
list = g_list_next (list), nth_drawable++)
|
||||
{
|
||||
GimpDrawable *drawable = list->data;
|
||||
|
||||
gimp_drawable_convert_type (drawable, image,
|
||||
gimp_drawable_get_base_type (drawable),
|
||||
precision, TRUE);
|
||||
|
||||
if (progress)
|
||||
gimp_progress_set_value (progress,
|
||||
(gdouble) nth_drawable / (gdouble) n_drawables);
|
||||
}
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
gimp_image_precision_changed (image);
|
||||
g_object_thaw_notify (G_OBJECT (image));
|
||||
|
||||
if (progress)
|
||||
gimp_progress_end (progress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indexed color conversion machinery
|
||||
|
|
|
@ -36,6 +36,10 @@ gboolean gimp_image_convert (GimpImage *image,
|
|||
GimpProgress *progress,
|
||||
GError **error);
|
||||
|
||||
void gimp_image_convert_precision (GimpImage *image,
|
||||
GimpPrecision precision,
|
||||
GimpProgress *progress);
|
||||
|
||||
void gimp_image_convert_set_dither_matrix (const guchar *matrix,
|
||||
gint width,
|
||||
gint height);
|
||||
|
|
|
@ -76,6 +76,18 @@ gimp_image_undo_push_image_type (GimpImage *image,
|
|||
NULL);
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_image_undo_push_image_precision (GimpImage *image,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
|
||||
return gimp_image_undo_push (image, GIMP_TYPE_IMAGE_UNDO,
|
||||
GIMP_UNDO_IMAGE_PRECISION, undo_desc,
|
||||
GIMP_DIRTY_IMAGE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_image_undo_push_image_size (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
GimpUndo * gimp_image_undo_push_image_type (GimpImage *image,
|
||||
const gchar *undo_desc);
|
||||
GimpUndo * gimp_image_undo_push_image_precision (GimpImage *image,
|
||||
const gchar *undo_desc);
|
||||
GimpUndo * gimp_image_undo_push_image_size (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
gint previous_origin_x,
|
||||
|
|
|
@ -507,6 +507,9 @@ gimp_image_undo_pop_stack (GimpImage *image,
|
|||
if (accum.mode_changed)
|
||||
gimp_image_mode_changed (image);
|
||||
|
||||
if (accum.precision_changed)
|
||||
gimp_image_precision_changed (image);
|
||||
|
||||
if (accum.size_changed)
|
||||
gimp_image_size_changed_detailed (image,
|
||||
accum.previous_origin_x,
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
enum
|
||||
{
|
||||
MODE_CHANGED,
|
||||
PRECISION_CHANGED,
|
||||
ALPHA_CHANGED,
|
||||
FLOATING_SELECTION_CHANGED,
|
||||
ACTIVE_LAYER_CHANGED,
|
||||
|
@ -161,6 +162,7 @@ static gchar * gimp_image_get_description (GimpViewable *viewable,
|
|||
gchar **tooltip);
|
||||
|
||||
static void gimp_image_real_mode_changed (GimpImage *image);
|
||||
static void gimp_image_real_precision_changed(GimpImage *image);
|
||||
static void gimp_image_real_size_changed_detailed
|
||||
(GimpImage *image,
|
||||
gint previous_origin_x,
|
||||
|
@ -252,6 +254,15 @@ gimp_image_class_init (GimpImageClass *klass)
|
|||
gimp_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gimp_image_signals[PRECISION_CHANGED] =
|
||||
g_signal_new ("precision-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpImageClass, precision_changed),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
gimp_image_signals[ALPHA_CHANGED] =
|
||||
g_signal_new ("alpha-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
|
@ -536,6 +547,7 @@ gimp_image_class_init (GimpImageClass *klass)
|
|||
viewable_class->get_description = gimp_image_get_description;
|
||||
|
||||
klass->mode_changed = gimp_image_real_mode_changed;
|
||||
klass->precision_changed = gimp_image_real_precision_changed;
|
||||
klass->alpha_changed = NULL;
|
||||
klass->floating_selection_changed = NULL;
|
||||
klass->active_layer_changed = NULL;
|
||||
|
@ -1172,6 +1184,12 @@ gimp_image_real_mode_changed (GimpImage *image)
|
|||
gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_image_real_precision_changed (GimpImage *image)
|
||||
{
|
||||
gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_image_real_size_changed_detailed (GimpImage *image,
|
||||
gint previous_origin_x,
|
||||
|
@ -2278,6 +2296,14 @@ gimp_image_mode_changed (GimpImage *image)
|
|||
g_signal_emit (image, gimp_image_signals[MODE_CHANGED], 0);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_precision_changed (GimpImage *image)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (image));
|
||||
|
||||
g_signal_emit (image, gimp_image_signals[PRECISION_CHANGED], 0);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_alpha_changed (GimpImage *image)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@ struct _GimpImageClass
|
|||
|
||||
/* signals */
|
||||
void (* mode_changed) (GimpImage *image);
|
||||
void (* precision_changed) (GimpImage *image);
|
||||
void (* alpha_changed) (GimpImage *image);
|
||||
void (* floating_selection_changed) (GimpImage *image);
|
||||
void (* active_layer_changed) (GimpImage *image);
|
||||
|
@ -214,6 +215,7 @@ void gimp_image_get_visible_array (const GimpImage *image,
|
|||
/* emitting image signals */
|
||||
|
||||
void gimp_image_mode_changed (GimpImage *image);
|
||||
void gimp_image_precision_changed (GimpImage *image);
|
||||
void gimp_image_alpha_changed (GimpImage *image);
|
||||
void gimp_image_invalidate (GimpImage *image,
|
||||
gint x,
|
||||
|
|
|
@ -160,6 +160,10 @@ gimp_image_undo_constructed (GObject *object)
|
|||
image_undo->base_type = gimp_image_base_type (image);
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_IMAGE_PRECISION:
|
||||
image_undo->precision = gimp_image_get_precision (image);
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_IMAGE_SIZE:
|
||||
image_undo->width = gimp_image_get_width (image);
|
||||
image_undo->height = gimp_image_get_height (image);
|
||||
|
@ -317,6 +321,19 @@ gimp_image_undo_pop (GimpUndo *undo,
|
|||
}
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_IMAGE_PRECISION:
|
||||
{
|
||||
GimpPrecision precision;
|
||||
|
||||
precision = image_undo->precision;
|
||||
image_undo->precision = gimp_image_get_precision (image);
|
||||
g_object_set (image, "precision", precision, NULL);
|
||||
|
||||
if (image_undo->precision != gimp_image_get_precision (image))
|
||||
accum->precision_changed = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_IMAGE_SIZE:
|
||||
{
|
||||
gint width;
|
||||
|
|
|
@ -37,6 +37,7 @@ struct _GimpImageUndo
|
|||
GimpUndo parent_instance;
|
||||
|
||||
GimpImageBaseType base_type;
|
||||
GimpPrecision precision;
|
||||
gint width;
|
||||
gint height;
|
||||
gint previous_origin_x;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
struct _GimpUndoAccumulator
|
||||
{
|
||||
gboolean mode_changed;
|
||||
gboolean precision_changed;
|
||||
|
||||
gboolean size_changed;
|
||||
gint previous_origin_x;
|
||||
|
|
|
@ -116,6 +116,9 @@
|
|||
#define GIMP_HELP_IMAGE_CONVERT_RGB "gimp-image-convert-rgb"
|
||||
#define GIMP_HELP_IMAGE_CONVERT_GRAYSCALE "gimp-image-convert-grayscale"
|
||||
#define GIMP_HELP_IMAGE_CONVERT_INDEXED "gimp-image-convert-indexed"
|
||||
#define GIMP_HELP_IMAGE_CONVERT_U8 "gimp-image-convert-u8"
|
||||
#define GIMP_HELP_IMAGE_CONVERT_U16 "gimp-image-convert-u16"
|
||||
#define GIMP_HELP_IMAGE_CONVERT_FLOAT "gimp-image-convert-float"
|
||||
#define GIMP_HELP_IMAGE_FLIP_HORIZONTAL "gimp-image-flip-horizontal"
|
||||
#define GIMP_HELP_IMAGE_FLIP_VERTICAL "gimp-image-flip-vertical"
|
||||
#define GIMP_HELP_IMAGE_ROTATE_90 "gimp-image-rotate-90"
|
||||
|
|
|
@ -320,6 +320,12 @@
|
|||
<placeholder name="Color Profile" />
|
||||
<separator />
|
||||
</menu>
|
||||
<menu action="image-precision-menu" name="Precision">
|
||||
<menuitem action="image-convert-u8" />
|
||||
<menuitem action="image-convert-u16" />
|
||||
<menuitem action="image-convert-float" />
|
||||
<separator />
|
||||
</menu>
|
||||
<menu action="image-transform-menu" name="Transform">
|
||||
<placeholder name="Flip">
|
||||
<menuitem action="image-flip-horizontal" />
|
||||
|
|
Loading…
Reference in New Issue