#!/usr/bin/perl # implements some algorithms described in (the otherwise very bad) # http://www.biocomputer.com/Thesis.html # these are all simple 2x2 kernels, fast but relatively effective use Gimp::Feature 'pdl'; use Gimp 1.098; use Gimp::Fu; use PDL::LiteF; 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] >= ($drawable->offsets)[0]+$drawable->width; $bounds[3]-- if $bounds[1]+$bounds[3] >= ($drawable->offsets)[1]+$drawable->height; { my $src = new PixelRgn ($drawable,@bounds[0,1],$bounds[2]+1,$bounds[3]+1,0,0); my $dst = new 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", "Marc Lehmann", "Marc Lehmann <pcg\@goof.com>", "19990725", N_"<Image>/Filters/Blur/2x2 Blur", "RGB*, GRAY*", [], 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", "Marc Lehmann", "Marc Lehmann <pcg\@goof.com>", "19990725", N_"<Image>/Filters/Enhance/2x2 Contrast Enhance", "RGB*, GRAY*", [], 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).", "Marc Lehmann", "Marc Lehmann <pcg\@goof.com>", "19990725", N_"<Image>/Filters/Edge-Detect/2x2 Edge Detect", "RGB*, GRAY*", [], 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; =head1 LICENSE Copyright Marc Lehman. Distributed under the same terms as Gimp-Perl. =cut