Difference between revisions of "ImageMagick"
(2 intermediate revisions by the same user not shown) | |||
Line 29: | Line 29: | ||
The default operation: Src (the foreground) is copied over dst (the background). | The default operation: Src (the foreground) is copied over dst (the background). | ||
+ | |||
+ | To copy src behind dst, use <code>dst_over</code>. | ||
<syntaxhighlight lang=bash> | <syntaxhighlight lang=bash> | ||
− | |||
# The method may be omitted here | # The method may be omitted here | ||
composite -compose fg.png bg.png fg_on_bg.png | composite -compose fg.png bg.png fg_on_bg.png | ||
# More verbosely | # More verbosely | ||
composite -compose over fg.png bg.png fg_on_bg.png | composite -compose over fg.png bg.png fg_on_bg.png | ||
+ | # Src behind dst | ||
+ | composite -compose dst_over bg.png fg.png fg_on_bg.png | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 43: | Line 46: | ||
# More verbosely | # More verbosely | ||
$bg->Composite(method => 'over', image => $fg); | $bg->Composite(method => 'over', image => $fg); | ||
+ | |||
+ | # Result is $fg | ||
+ | $fg->Composite(method => 'dst_over', image => $bg); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | ==== | + | ====in: Src with alpha mask of dst applied==== |
+ | |||
+ | <code>in</code> results in src seen through the alpha channel provided by dst. | ||
− | + | <code>dst_in</code> is the same, but swaps src and dst. | |
<syntaxhighlight lang=bash> | <syntaxhighlight lang=bash> | ||
− | composite -compose | + | composite -compose in image.png alpha-mask.png masked-image.png |
+ | composite -compose dst_in alpha-mask.png image.png masked-image.png | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang=perl> | <syntaxhighlight lang=perl> | ||
− | # Result is $ | + | # Result is whichever object whose method is called |
− | $ | + | $alpha_mask->Composite(method => 'in', image => $image); |
+ | $image->Composite(method => 'dst_in', image => $alpha_mask); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 101: | Line 111: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | == | + | <syntaxhighlight lang=perl> |
+ | my $alpha_mask = $gray_mask->Clone; | ||
+ | $alpha_mask->Set(alpha => 'shape'); | ||
+ | </syntaxhighlight> | ||
− | + | ===Trim on only particular edges=== | |
− | <syntaxhighlight lang= | + | The solution described in [http://www.imagemagick.org/Usage/crop/#trim_oneside the documentation on cutting and bordering] is to add a white bar and a black bar to the opposite edge of the image, apply a full trim (which will then only impact the edge opposite the bars, plus the outermost of the two bars added), then chop off the remaining bar. |
− | + | ||
+ | This is a Perl implementation of that advice, encapsulated into a function <code>trim_sides(''image'', ''trim-top'', ''trim-right'', ''trim-bottom'', ''trim-left'')</code>, where the parameters after the image are boolean. The operation is in-place, but the image object is also returned, so e.g. <code>$image->Clone</code> can be passed in order to operate on a copy. | ||
+ | |||
+ | <syntaxhighlight lang=perl> | ||
+ | sub _directed_trim_impl { | ||
+ | my $image = shift; | ||
+ | my $bar_width = shift; | ||
+ | my $bar_height = shift; | ||
+ | my $gravity = shift; | ||
+ | |||
+ | my $bar_geom = "${bar_width}x${bar_height}"; | ||
+ | |||
+ | # Add white and black bars on the indicated side to prevent trimming on | ||
+ | # the edges touching the bars | ||
+ | |||
+ | # PSM: Can't say for sure why this is necessary, but without this dummy | ||
+ | # splice, the first bar ends up in a strange place. | ||
+ | $image->Splice(geometry => '0x0', gravity => $gravity); | ||
+ | |||
+ | for(qw/white black/) { | ||
+ | $image->Splice(geometry=>$bar_geom, gravity=>$gravity, background=>$_); | ||
+ | } | ||
+ | |||
+ | # Trim the edge not touching the bars | ||
+ | $image->Trim; | ||
+ | |||
+ | # Repage | ||
+ | $image->Set(page=>'0x0+0+0'); | ||
+ | |||
+ | # Remove the bar not trimmed | ||
+ | $image->Chop(geometry=>$bar_geom, gravity=>$gravity); | ||
+ | |||
+ | return $image; | ||
+ | } | ||
+ | |||
+ | sub trim_sides { | ||
+ | my($image, $trim_top, $trim_right, $trim_bottom, $trim_left) = @_; | ||
+ | _directed_trim_impl($image, 0, 1, 'south') if $trim_top; | ||
+ | _directed_trim_impl($image, 1, 0, 'west') if $trim_right; | ||
+ | _directed_trim_impl($image, 0, 1, 'north') if $trim_bottom; | ||
+ | _directed_trim_impl($image, 1, 0, 'east') if $trim_left; | ||
+ | $image; | ||
+ | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 19:13, 2 January 2015
ImageMagick is a common image processing program (convert
) and library (e.g. PerlMagick, aka Image::Magick
).
Contents
Snippets
Composite
A Composite
operation combines two images. Useful for such things as adding backgrounds to partially transparent images.
General
In the docs, the "src" (or "overlay") is combined with the "dst" (or "background") using a compose method.
composite -compose METHOD SRC.png DST.png COMPOSED.png
When using Perl, the operation is destructive of the dst image. Use the Clone
method to operate on a copy while preserving the original.
# Result is $dst
$dst->Composite(compose => 'METHOD', image => $src);
# Result is $composed, $dst is unchanged
my $composed = $dst->Clone;
$composed->Composite(...);
over: Copy src on top of dst
The default operation: Src (the foreground) is copied over dst (the background).
To copy src behind dst, use dst_over
.
# The method may be omitted here
composite -compose fg.png bg.png fg_on_bg.png
# More verbosely
composite -compose over fg.png bg.png fg_on_bg.png
# Src behind dst
composite -compose dst_over bg.png fg.png fg_on_bg.png
# Result is $bg
$bg->Composite(image => $fg);
# More verbosely
$bg->Composite(method => 'over', image => $fg);
# Result is $fg
$fg->Composite(method => 'dst_over', image => $bg);
in: Src with alpha mask of dst applied
in
results in src seen through the alpha channel provided by dst.
dst_in
is the same, but swaps src and dst.
composite -compose in image.png alpha-mask.png masked-image.png
composite -compose dst_in alpha-mask.png image.png masked-image.png
# Result is whichever object whose method is called
$alpha_mask->Composite(method => 'in', image => $image);
$image->Composite(method => 'dst_in', image => $alpha_mask);
New image filled with color
export COLOR=white
export WIDTH=800
export HEIGHT=600
convert -size ${WIDTH}x${HEIGHT} xc:${COLOR} filled.png
my $color = 'white';
my $width = 800;
my $height = 600;
my $filled = new Image::Magick size => "${width}x${height}";
$filled->Read("xc:$color");
New image the same size as an existing image
my $new_image = new Image::Magick size => join('x', $existing_image->Get('width','height'));
Fill the background of an existing (partly transparent) image with a color
my $bg_color = 'white';
my $bg = new Image::Magick size => join('x', $fg->Get('width','height'));
$bg->Read("xc:$bg_color");
# Either put the result in the new image (result $bg)
$bg->Composite(image => $fg);
# Or mutate the existing foreground image (result $fg)
$fg->Composite(compose => 'dst_over', image => $bg);
Change a grayscale image to an alpha mask image (white as opaque)
convert gray-mask.png -alpha shape alpha-mask.png
my $alpha_mask = $gray_mask->Clone;
$alpha_mask->Set(alpha => 'shape');
Trim on only particular edges
The solution described in the documentation on cutting and bordering is to add a white bar and a black bar to the opposite edge of the image, apply a full trim (which will then only impact the edge opposite the bars, plus the outermost of the two bars added), then chop off the remaining bar.
This is a Perl implementation of that advice, encapsulated into a function trim_sides(image, trim-top, trim-right, trim-bottom, trim-left)
, where the parameters after the image are boolean. The operation is in-place, but the image object is also returned, so e.g. $image->Clone
can be passed in order to operate on a copy.
sub _directed_trim_impl {
my $image = shift;
my $bar_width = shift;
my $bar_height = shift;
my $gravity = shift;
my $bar_geom = "${bar_width}x${bar_height}";
# Add white and black bars on the indicated side to prevent trimming on
# the edges touching the bars
# PSM: Can't say for sure why this is necessary, but without this dummy
# splice, the first bar ends up in a strange place.
$image->Splice(geometry => '0x0', gravity => $gravity);
for(qw/white black/) {
$image->Splice(geometry=>$bar_geom, gravity=>$gravity, background=>$_);
}
# Trim the edge not touching the bars
$image->Trim;
# Repage
$image->Set(page=>'0x0+0+0');
# Remove the bar not trimmed
$image->Chop(geometry=>$bar_geom, gravity=>$gravity);
return $image;
}
sub trim_sides {
my($image, $trim_top, $trim_right, $trim_bottom, $trim_left) = @_;
_directed_trim_impl($image, 0, 1, 'south') if $trim_top;
_directed_trim_impl($image, 1, 0, 'west') if $trim_right;
_directed_trim_impl($image, 0, 1, 'north') if $trim_bottom;
_directed_trim_impl($image, 1, 0, 'east') if $trim_left;
$image;
}