Skip to content

Instantly share code, notes, and snippets.

@jussikinnula
Last active November 19, 2015 08:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jussikinnula/b579938bd2a36e743b02 to your computer and use it in GitHub Desktop.
Save jussikinnula/b579938bd2a36e743b02 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use Imager;
use File::Path qw(make_path);
use File::Basename;
sub match_colors {
my ($color1, $color2, $fuzziness) = @_;
my ($color1_red, $color1_green, $color1_blue) = $color1->rgba();
my ($color2_red, $color2_green, $color2_blue) = $color2->rgba();
return 1 if
($color1_red < ($color2_red - $fuzziness) or $color1_red > ($color2_red + $fuzziness))
and ($color1_green < ($color2_green - $fuzziness) or $color1_green > ($color2_green + $fuzziness))
and ($color1_blue < ($color2_blue - $fuzziness) or $color1_blue > ($color2_blue + $fuzziness))
;
}
sub trim {
my ($imager, $fuzziness) = @_;
my $top = 0;
my $left = 0;
my $right = $imager->getwidth();
my $bottom = $imager->getheight();
my $first_pixel_color = $imager->getpixel(
x => $left,
y => $top,
);
for (my $y = $top; $y < $bottom; $y++) {
my $match = 0;
for (my $x = $left; $x < $right; $x++) {
if (match_colors(
$first_pixel_color,
$imager->getpixel(
x => $x,
y => $y,
),
$fuzziness)
) {
$match = 1;
last;
}
}
if ($match) {
$top = $y;
last;
}
}
for (my $y = $bottom; $y > $top; $y--) {
my $match = 0;
for (my $x = $left; $x < $right; $x++) {
if (match_colors(
$first_pixel_color,
$imager->getpixel(
x => $x,
y => $y-1,
),
$fuzziness)
) {
$match = 1;
last;
}
}
if ($match) {
$bottom = $y;
last;
}
}
for (my $x = $left; $x < $right; $x++) {
my $match = 0;
for (my $y = $top; $y < $bottom; $y++) {
if (match_colors(
$first_pixel_color,
$imager->getpixel(
x => $x,
y => $y,
),
$fuzziness)
) {
$match = 1;
last;
}
}
if ($match) {
$left = $x;
last;
}
}
for (my $x = $right; $x > $left; $x--) {
my $match = 0;
for (my $y = $top; $y < $bottom; $y++) {
if (match_colors(
$first_pixel_color,
$imager->getpixel(
x => $x-1,
y => $y,
),
$fuzziness)
) {
$match = 1;
last;
}
}
if ($match) {
$right = $x;
last;
}
}
return $top, $left, $right, $bottom;
}
die "Usage: trim.pl [source_image] [source_image] [fuzziness]\n"
unless @ARGV and $ARGV[0] and $ARGV[1];
my ($source, $target, $fuzziness) = @ARGV;
$fuzziness = $fuzziness || 0;
my ($target_filename, $target_path) = fileparse($target);
my $target_filetype = (split(/\./, $target_filename))[1] || 'png';
$target_filetype = 'jpeg' if $target_filetype eq 'jpg' or $target_filetype eq 'jpe';
my $imager = Imager->new( file => $source )
or die "Cannot open $source -file: ", Imager->errstr();
# Trim background
my ($top, $left, $right, $bottom) = trim($imager, $fuzziness);
$imager = $imager->crop(
left => $left,
right => $right,
top => $top,
bottom => $bottom,
);
# Fit the original image to a square box
# First create directory for the file
make_path($target_path) if $target_path and $target_path ne './';
# Then store it
$imager->write( file => $target, type => $target_filetype )
or die "Cannot write $target -file: ", Imager->errstr();
print "Done.\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment