450 lines
15 KiB
Plaintext
450 lines
15 KiB
Plaintext
|
# PIKA - Photo and Image Kooker Application
|
||
|
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||
|
|
||
|
# This program is free software: you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation; either version 3 of the License, or
|
||
|
# (at your option) any later version.
|
||
|
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
|
||
|
# You should have received a copy of the GNU General Public License
|
||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
|
||
|
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
|
||
|
|
||
|
sub image_select_color {
|
||
|
$blurb = <<'BLURB';
|
||
|
Create a selection by selecting all pixels (in the specified drawable)
|
||
|
with the same (or similar) color to that specified.
|
||
|
BLURB
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This tool creates a selection over the specified image. A by-color
|
||
|
selection is determined by the supplied color under the constraints of
|
||
|
the current context settings. Essentially, all pixels (in the drawable)
|
||
|
that have color sufficiently close to the specified color (as
|
||
|
determined by the threshold and criterion context values) are included
|
||
|
in the selection. To select transparent regions, the color specified
|
||
|
must also have minimum alpha.
|
||
|
|
||
|
|
||
|
This procedure is affected by the following context setters:
|
||
|
pika_context_set_antialias(), pika_context_set_feather(),
|
||
|
pika_context_set_feather_radius(), pika_context_set_sample_merged(),
|
||
|
pika_context_set_sample_criterion(), pika_context_set_sample_threshold(),
|
||
|
pika_context_set_sample_transparent().
|
||
|
|
||
|
|
||
|
In the case of a merged sampling, the supplied drawable is ignored.
|
||
|
HELP
|
||
|
|
||
|
&david_pdb_misc('2010', '2.8');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The affected image' },
|
||
|
{ name => 'operation', type => 'enum PikaChannelOps',
|
||
|
desc => 'The selection operation' },
|
||
|
{ name => 'drawable', type => 'drawable',
|
||
|
desc => 'The affected drawable' },
|
||
|
{ name => 'color', type => 'color',
|
||
|
desc => 'The color to select' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
|
||
|
|
||
|
if (pdb_context->sample_merged ||
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), image, 0, error))
|
||
|
{
|
||
|
GList *drawables = g_list_prepend (NULL, drawable);
|
||
|
pika_channel_select_by_color (pika_image_get_mask (image), drawables,
|
||
|
pdb_context->sample_merged,
|
||
|
&color,
|
||
|
pdb_context->sample_threshold,
|
||
|
pdb_context->sample_transparent,
|
||
|
pdb_context->sample_criterion,
|
||
|
operation,
|
||
|
pdb_context->antialias,
|
||
|
pdb_context->feather,
|
||
|
pdb_context->feather_radius_x,
|
||
|
pdb_context->feather_radius_y);
|
||
|
g_list_free (drawables);
|
||
|
}
|
||
|
else
|
||
|
success = FALSE;
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
sub image_select_contiguous_color {
|
||
|
$blurb = <<'BLURB';
|
||
|
Create a selection by selecting all pixels around specified coordinates
|
||
|
with the same (or similar) color to that at the coordinates.
|
||
|
BLURB
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This tool creates a contiguous selection over the specified image. A
|
||
|
contiguous color selection is determined by a seed fill under the
|
||
|
constraints of the current context settings. Essentially, the color
|
||
|
at the specified coordinates (in the drawable) is measured and the
|
||
|
selection expands outwards from that point to any adjacent pixels
|
||
|
which are not significantly different (as determined by the threshold
|
||
|
and criterion context settings). This process continues until no more
|
||
|
expansion is possible. If antialiasing is turned on, the final
|
||
|
selection mask will contain intermediate values based on close misses
|
||
|
to the threshold bar at pixels along the seed fill boundary.
|
||
|
|
||
|
|
||
|
This procedure is affected by the following context setters:
|
||
|
pika_context_set_antialias(), pika_context_set_feather(),
|
||
|
pika_context_set_feather_radius(), pika_context_set_sample_merged(),
|
||
|
pika_context_set_sample_criterion(), pika_context_set_sample_threshold(),
|
||
|
pika_context_set_sample_transparent(), pika_context_set_diagonal_neighbors().
|
||
|
|
||
|
|
||
|
In the case of a merged sampling, the supplied drawable is ignored.
|
||
|
If the sample is merged, the specified coordinates are relative to the
|
||
|
image origin; otherwise, they are relative to the drawable's origin.
|
||
|
HELP
|
||
|
|
||
|
&david_pdb_misc('2010', '2.8');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The affected image' },
|
||
|
{ name => 'operation', type => 'enum PikaChannelOps',
|
||
|
desc => 'The selection operation' },
|
||
|
{ name => 'drawable', type => 'drawable',
|
||
|
desc => 'The affected drawable' },
|
||
|
{ name => 'x', type => 'float',
|
||
|
desc => 'x coordinate of initial seed fill point: (image
|
||
|
coordinates)' },
|
||
|
{ name => 'y', type => 'float',
|
||
|
desc => 'y coordinate of initial seed fill point: (image
|
||
|
coordinates)' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
|
||
|
|
||
|
if (pdb_context->sample_merged ||
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), image, 0, error))
|
||
|
{
|
||
|
|
||
|
pika_channel_select_fuzzy (pika_image_get_mask (image),
|
||
|
drawable,
|
||
|
pdb_context->sample_merged,
|
||
|
x, y,
|
||
|
pdb_context->sample_threshold,
|
||
|
pdb_context->sample_transparent,
|
||
|
pdb_context->sample_criterion,
|
||
|
pdb_context->diagonal_neighbors,
|
||
|
operation,
|
||
|
pdb_context->antialias,
|
||
|
pdb_context->feather,
|
||
|
pdb_context->feather_radius_x,
|
||
|
pdb_context->feather_radius_y);
|
||
|
}
|
||
|
else
|
||
|
success = FALSE;
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
sub image_select_rectangle {
|
||
|
$blurb = 'Create a rectangular selection over the specified image;';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This tool creates a rectangular selection over the specified
|
||
|
image. The rectangular region can be either added to, subtracted from,
|
||
|
or replace the contents of the previous selection mask.
|
||
|
|
||
|
|
||
|
This procedure is affected by the following context setters:
|
||
|
pika_context_set_feather(), pika_context_set_feather_radius().
|
||
|
HELP
|
||
|
|
||
|
&mitch_pdb_misc('2010', '2.8');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' },
|
||
|
{ name => 'operation', type => 'enum PikaChannelOps',
|
||
|
desc => 'The selection operation' },
|
||
|
{ name => 'x', type => 'float',
|
||
|
desc => 'x coordinate of upper-left corner of rectangle' },
|
||
|
{ name => 'y', type => 'float',
|
||
|
desc => 'y coordinate of upper-left corner of rectangle' },
|
||
|
{ name => 'width', type => '0 < float',
|
||
|
desc => 'The width of the rectangle' },
|
||
|
{ name => 'height', type => '0 < float',
|
||
|
desc => 'The height of the rectangle' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
|
||
|
|
||
|
pika_channel_select_rectangle (pika_image_get_mask (image),
|
||
|
(gint) x, (gint) y,
|
||
|
(gint) width, (gint) height,
|
||
|
operation,
|
||
|
pdb_context->feather,
|
||
|
pdb_context->feather_radius_x,
|
||
|
pdb_context->feather_radius_y,
|
||
|
TRUE);
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
sub image_select_round_rectangle {
|
||
|
$blurb = 'Create a rectangular selection with round corners over the specified image;';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This tool creates a rectangular selection with round corners over the
|
||
|
specified image. The rectangular region can be either added to,
|
||
|
subtracted from, or replace the contents of the previous selection
|
||
|
mask.
|
||
|
|
||
|
|
||
|
This procedure is affected by the following context setters:
|
||
|
pika_context_set_antialias(), pika_context_set_feather(),
|
||
|
pika_context_set_feather_radius().
|
||
|
HELP
|
||
|
|
||
|
&martin_pdb_misc('2010', '2.8');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' },
|
||
|
{ name => 'operation', type => 'enum PikaChannelOps',
|
||
|
desc => 'The selection operation' },
|
||
|
{ name => 'x', type => 'float',
|
||
|
desc => 'x coordinate of upper-left corner of rectangle' },
|
||
|
{ name => 'y', type => 'float',
|
||
|
desc => 'y coordinate of upper-left corner of rectangle' },
|
||
|
{ name => 'width', type => '0 < float',
|
||
|
desc => 'The width of the rectangle' },
|
||
|
{ name => 'height', type => '0 < float',
|
||
|
desc => 'The height of the rectangle' },
|
||
|
{ name => 'corner_radius_x', type => '0 < float < PIKA_MAX_IMAGE_SIZE',
|
||
|
desc => 'The corner radius in X direction' },
|
||
|
{ name => 'corner_radius_y', type => '0 < float < PIKA_MAX_IMAGE_SIZE',
|
||
|
desc => 'The corner radius in Y direction' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
|
||
|
|
||
|
pika_channel_select_round_rect (pika_image_get_mask (image),
|
||
|
(gint) x, (gint) y,
|
||
|
(gint) width, (gint) height,
|
||
|
corner_radius_x,
|
||
|
corner_radius_y,
|
||
|
operation,
|
||
|
pdb_context->antialias,
|
||
|
pdb_context->feather,
|
||
|
pdb_context->feather_radius_x,
|
||
|
pdb_context->feather_radius_y,
|
||
|
TRUE);
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
sub image_select_ellipse {
|
||
|
$blurb = 'Create an elliptical selection over the specified image.';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This tool creates an elliptical selection over the specified
|
||
|
image. The elliptical region can be either added to, subtracted from,
|
||
|
or replace the contents of the previous selection mask.
|
||
|
|
||
|
|
||
|
This procedure is affected by the following context setters:
|
||
|
pika_context_set_antialias(), pika_context_set_feather(),
|
||
|
pika_context_set_feather_radius().
|
||
|
HELP
|
||
|
|
||
|
&mitch_pdb_misc('2010', '2.8');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' },
|
||
|
{ name => 'operation', type => 'enum PikaChannelOps',
|
||
|
desc => 'The selection operation' },
|
||
|
{ name => 'x', type => 'float',
|
||
|
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
|
||
|
{ name => 'y', type => 'float',
|
||
|
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
|
||
|
{ name => 'width', type => '0 < float',
|
||
|
desc => 'The width of the ellipse' },
|
||
|
{ name => 'height', type => '0 < float',
|
||
|
desc => 'The height of the ellipse' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
|
||
|
|
||
|
pika_channel_select_ellipse (pika_image_get_mask (image),
|
||
|
(gint) x, (gint) y,
|
||
|
(gint) width, (gint) height,
|
||
|
operation,
|
||
|
pdb_context->antialias,
|
||
|
pdb_context->feather,
|
||
|
pdb_context->feather_radius_x,
|
||
|
pdb_context->feather_radius_y,
|
||
|
TRUE);
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
sub image_select_polygon {
|
||
|
$blurb = 'Create a polygonal selection over the specified image.';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This tool creates a polygonal selection over the specified image. The
|
||
|
polygonal region can be either added to, subtracted from, or replace
|
||
|
the contents of the previous selection mask. The polygon is specified
|
||
|
through an array of floating point numbers and its length. The length
|
||
|
of array must be 2n, where n is the number of points. Each point is
|
||
|
defined by 2 floating point values which correspond to the x and y
|
||
|
coordinates. If the final point does not connect to the starting
|
||
|
point, a connecting segment is automatically added.
|
||
|
|
||
|
|
||
|
This procedure is affected by the following context setters:
|
||
|
pika_context_set_antialias(), pika_context_set_feather(),
|
||
|
pika_context_set_feather_radius().
|
||
|
HELP
|
||
|
|
||
|
&mitch_pdb_misc('2010', '2.8');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' },
|
||
|
{ name => 'operation', type => 'enum PikaChannelOps',
|
||
|
desc => 'The selection operation' },
|
||
|
{ name => 'segs', type => 'floatarray',
|
||
|
desc => 'Array of points: { p1.x, p1.y, p2.x, p2.y, ...,
|
||
|
pn.x, pn.y}',
|
||
|
array => { type => '2 <= int32',
|
||
|
desc => 'Number of points (count 1 coordinate as two
|
||
|
points)' } }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
|
||
|
|
||
|
pika_channel_select_polygon (pika_image_get_mask (image),
|
||
|
_("Free Select"),
|
||
|
num_segs / 2,
|
||
|
(PikaVector2 *) segs,
|
||
|
operation,
|
||
|
pdb_context->antialias,
|
||
|
pdb_context->feather,
|
||
|
pdb_context->feather_radius_x,
|
||
|
pdb_context->feather_radius_y,
|
||
|
TRUE);
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
sub image_select_item {
|
||
|
$blurb = 'Transforms the specified item into a selection';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This procedure renders the item's outline into the current selection
|
||
|
of the image the item belongs to. What exactly the item's outline is
|
||
|
depends on the item type: for layers, it's the layer's alpha channel,
|
||
|
for vectors the vector's shape.
|
||
|
|
||
|
|
||
|
This procedure is affected by the following context setters:
|
||
|
pika_context_set_antialias(), pika_context_set_feather(),
|
||
|
pika_context_set_feather_radius().
|
||
|
HELP
|
||
|
|
||
|
&mitch_pdb_misc('2010', '2.8');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' },
|
||
|
{ name => 'operation', type => 'enum PikaChannelOps',
|
||
|
desc => 'The desired operation with current selection' },
|
||
|
{ name => 'item', type => 'item',
|
||
|
desc => 'The item to render to the selection' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
if (pika_pdb_item_is_attached (item, image, 0, error))
|
||
|
{
|
||
|
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
|
||
|
|
||
|
pika_item_to_selection (item, operation,
|
||
|
pdb_context->antialias,
|
||
|
pdb_context->feather,
|
||
|
pdb_context->feather_radius_x,
|
||
|
pdb_context->feather_radius_y);
|
||
|
}
|
||
|
else
|
||
|
success = FALSE;
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
@headers = qw("libpikabase/pikabase.h"
|
||
|
"core/pikachannel-select.h"
|
||
|
"pikapdb-utils.h"
|
||
|
"pikapdbcontext.h"
|
||
|
"pika-intl.h");
|
||
|
|
||
|
@procs = qw(image_select_color
|
||
|
image_select_contiguous_color
|
||
|
image_select_rectangle
|
||
|
image_select_round_rectangle
|
||
|
image_select_ellipse
|
||
|
image_select_polygon
|
||
|
image_select_item);
|
||
|
|
||
|
%exports = (app => [@procs], lib => [@procs]);
|
||
|
|
||
|
$desc = 'Selection procedures';
|
||
|
$doc_title = 'pikaimageselect';
|
||
|
$doc_short_desc = "Modify the image's selection.";
|
||
|
$doc_long_desc = "Functions to modify the image's selection.";
|
||
|
|
||
|
1;
|