Sponsoring The Perl Toolchain Summit 2025: Help make this important event another success Learn more

#!/usr/bin/perl -w
use Gimp;
use strict;
sub iterate {
my ($drawable,$message,$kernel)=@_;
Gimp->progress_init ($message);
my @bounds = $drawable->bounds;
my @off = $drawable->offsets;
$bounds[2]-- if $bounds[0]+$bounds[2] >= $off[0]+$drawable->width;
$bounds[3]-- if $bounds[1]+$bounds[3] >= $off[1]+$drawable->height;
{
my $src = new Gimp::PixelRgn ($drawable,@bounds[0,1],$bounds[2]+1,$bounds[3]+1,0,0);
my $dst = new Gimp::PixelRgn ($drawable,@bounds,1,1);
my $iter = Gimp->pixel_rgns_register ($dst);
my $area = $bounds[2]*$bounds[3];
my $progress = 0;
do {
my ($x,$y,$w,$h)=($dst->x,$dst->y,$dst->w,$dst->h);
$dst->data($kernel->($src->get_rect($x,$y,$w+1,$h+1)->convert(short)));
$progress += $w*$h/$area;
Gimp->progress_update ($progress);
} while (Gimp->pixel_rgns_process ($iter));
}
Gimp->progress_update (1);
$drawable->merge_shadow (1);
$drawable->update (@bounds);
();
}
register "blur_2x2",
"smooth (low pass filter) an image using a fast 2x2 kernel",
"Low-pass filtering (smoothing) using a fast 2x2 kernel",
'', '', '',
N_"<Image>/Filters/Blur/2x2 Blur",
'', '',
sub {
my($image,$drawable)=@_;
iterate $drawable,
"2x2 smoothing...",
sub {
($_[0]->slice(":,0:-2,0:-2")+
$_[0]->slice(":,1:-1,0:-2")+
$_[0]->slice(":,1:-1,1:-1")+
$_[0]->slice(":,0:-2,1:-1"))>>2;
};
};
register "contrast_enhance_2x2",
"contrast enhance an image using a fast 2x2 kernel",
"Contrast Enhance an image using a fast 2x2 kernel",
'', '', '',
N_"<Image>/Filters/Enhance/2x2 Contrast Enhance",
'', '',
sub {
my($image,$drawable)=@_;
iterate $drawable,
"2x2 contrast enhancing...",
sub {
my $T = $_[0]->slice(":,0:-2,0:-2");
my $D = $_[0]->slice(":,1:-1,1:-1");
(($T<<1)-$D)->clip(0,255);
};
};
register "edge_detect_2x2",
"detects edges in an image using a fast 2x2 kernel",
"Detect edges in the image using a 2x2 kernel. It is similar to Sobel, yet sharper (and lower quality).",
'', '', '',
N_"<Image>/Filters/Edge-Detect/2x2 Edge Detect",
'', '',
sub {
my($image,$drawable)=@_;
iterate $drawable,
"2x2 cross gradient...",
sub {
my $T = $_[0]->slice(":,0:-2,0:-2");
my $R = $_[0]->slice(":,1:-1,0:-2");
my $D = $_[0]->slice(":,1:-1,1:-1");
abs(cat($T-$R,$T-$D))
->convert(byte)
->mv(3,0)
->maximum;
};
};
exit main;
__END__
=head1 NAME
blur_2x2/contrast_enhance_2x2/edge_detect_2x2 - Use a fast 2x2 kernel
to detect edges/enhance/smooth image
=head1 SYNOPSIS
<Image>/Filters/Edge-Detect/2x2 Edge Detect
<Image>/Filters/Blur/2x2 Blur
<Image>/Filters/Enhance/2x2 Contrast Enhance
=head1 DESCRIPTION
Detect edges in the image using a 2x2 kernel. It is similar to Sobel,
yet sharper (and lower quality).
Implements some algorithms described in (the otherwise very bad)
These are all simple 2x2 kernels, fast but relatively effective.
=head1 PARAMETERS
# none
=head1 IMAGE TYPES
RGB*, GRAY*
=head1 AUTHOR
Marc Lehmann <pcg@goof.com>
=head1 DATE
19990725
=head1 LICENSE
Distributed under the same terms as Gimp-Perl.