Added extra parameters to rubthrough so only a subimage of
authorArnar Mar Hrafnkelsson <addi@cpan.org>
Sat, 29 Mar 2003 12:24:05 +0000 (12:24 +0000)
committerArnar Mar Hrafnkelsson <addi@cpan.org>
Sat, 29 Mar 2003 12:24:05 +0000 (12:24 +0000)
the source image is copied.

Changes
Imager.pm
Imager.xs
MANIFEST
image.c
image.h
lib/Imager/Transformations.pod
t/t69rubthru.t

diff --git a/Changes b/Changes
index b93f9df..ef63b77 100644 (file)
--- a/Changes
+++ b/Changes
@@ -716,7 +716,8 @@ Revision history for Perl extension Imager.
           instead.
         - some older FT1 don't define TT_MS_LANGID_ENGLISH_GENERAL,
           which we use, define it if freetype doesn't.
-
+        - Added extra options to rubthrough() so only a subpart of
+          source image is used.
 =================================================================
 
         For latest versions check the Imager-devel pages:
index 6d282df..9ddd35c 100644 (file)
--- a/Imager.pm
+++ b/Imager.pm
@@ -1737,12 +1737,19 @@ sub transform2 {
 
 sub rubthrough {
   my $self=shift;
-  my %opts=(tx=>0,ty=>0,@_);
+  my %opts=(tx => 0,ty => 0, @_);
 
   unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
   unless ($opts{src} && $opts{src}->{IMG}) { $self->{ERRSTR}='empty input image for source'; return undef; }
 
-  unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $opts{tx},$opts{ty})) {
+  %opts = (src_minx => 0,
+          src_miny => 0,
+          src_maxx => $opts{src}->getwidth(),
+          src_maxy => $opts{src}->getheight(),
+          %opts);
+
+  unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $opts{tx}, $opts{ty},
+         $opts{src_minx}, $opts{src_miny}, $opts{src_maxx}, $opts{src_maxy})) {
     $self->{ERRSTR} = $self->_error_as_msg();
     return undef;
   }
index a6fb512..5e79c19 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -1478,11 +1478,16 @@ i_copy(im,src)
 
 
 undef_int
-i_rubthru(im,src,tx,ty)
+i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
     Imager::ImgRaw     im
     Imager::ImgRaw     src
               int     tx
               int     ty
+              int     src_minx
+              int     src_miny
+              int     src_maxx
+              int     src_maxy
+
 
 undef_int
 i_flipxy(im, direction)
index ac14cf1..d4cbfc2 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -77,6 +77,7 @@ lib/Imager/Font/Truetype.pm
 lib/Imager/Font/FreeType2.pm
 lib/Imager/Font/Win32.pm
 lib/Imager/Font/Wrap.pm
+lib/Imager/Font/Image.pm
 lib/Imager/Fountain.pm
 lib/Imager/interface.pod
 lib/Imager/Matrix2d.pm
diff --git a/image.c b/image.c
index 0b568a0..9de1e09 100644 (file)
--- a/image.c
+++ b/image.c
@@ -649,9 +649,10 @@ i_copy(i_img *im, i_img *src) {
 
 
 /*
-=item i_rubthru(im, src, tx, ty)
+=item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
 
-Takes the image I<src> and applies it at an original (I<tx>,I<ty>) in I<im>.
+Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
+overlays it at (I<tx>,I<ty>) on the image object.
 
 The alpha channel of each pixel in I<src> is used to control how much
 the existing colour in I<im> is replaced, if it is 255 then the colour
@@ -662,14 +663,17 @@ unmodified.
 */
 
 int
-i_rubthru(i_img *im,i_img *src,int tx,int ty) {
+i_rubthru(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny,
+         int src_maxx, int src_maxy) {
   int x, y, ttx, tty;
   int chancount;
   int chans[3];
   int alphachan;
   int ch;
 
-  mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d)\n", im, src, tx, ty));
+  mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d, src_minx %d, "
+         "src_miny %d, src_maxx %d, src_maxy %d)\n",
+         im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy));
   i_clear_error();
 
   if (im->channels == 3 && src->channels == 4) {
@@ -697,11 +701,10 @@ i_rubthru(i_img *im,i_img *src,int tx,int ty) {
        changed in a similar fashion - TC */
     int alpha;
     i_color pv, orig, dest;
-    ttx = tx;
-    for(x=0; x<src->xsize; x++) {
-      tty=ty;
-      for(y=0;y<src->ysize;y++) {
-        /* fprintf(stderr,"reading (%d,%d) writing (%d,%d).\n",x,y,ttx,tty); */
+    tty = ty;
+    for(y = src_miny; y < src_maxy; y++) {
+      ttx = tx;
+      for(x = src_minx; x < src_maxx; x++) {
         i_gpix(src, x,   y,   &pv);
         i_gpix(im,  ttx, tty, &orig);
         alpha = pv.channel[alphachan];
@@ -710,31 +713,30 @@ i_rubthru(i_img *im,i_img *src,int tx,int ty) {
                               + (255 - alpha) * orig.channel[ch])/255;
         }
         i_ppix(im, ttx, tty, &dest);
-        tty++;
+       ttx++;
       }
-      ttx++;
+      tty++;
     }
   }
   else {
     double alpha;
     i_fcolor pv, orig, dest;
 
-    ttx = tx;
-    for(x=0; x<src->xsize; x++) {
-      tty=ty;
-      for(y=0;y<src->ysize;y++) {
-        /* fprintf(stderr,"reading (%d,%d) writing (%d,%d).\n",x,y,ttx,tty); */
+    tty = ty;
+    for(y = src_miny; y < src_maxy; y++) {
+      ttx = tx;
+      for(x = src_minx; x < src_maxx; x++) {
         i_gpixf(src, x,   y,   &pv);
         i_gpixf(im,  ttx, tty, &orig);
         alpha = pv.channel[alphachan];
         for (ch = 0; ch < chancount; ++ch) {
           dest.channel[ch] = alpha * pv.channel[chans[ch]]
-                              + (1 - alpha) * orig.channel[ch];
+           + (1 - alpha) * orig.channel[ch];
         }
         i_ppixf(im, ttx, tty, &dest);
-        tty++;
+        ttx++;
       }
-      ttx++;
+      tty++;
     }
   }
 
diff --git a/image.h b/image.h
index 1acd9f8..e90d30f 100644 (file)
--- a/image.h
+++ b/image.h
@@ -211,7 +211,8 @@ void i_circle_aa   (i_img *im,float x, float y,float rad,i_color *val);
 void i_copyto      (i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty);
 void i_copyto_trans(i_img *im,i_img *src,int x1,int y1,int x2,int y2,int tx,int ty,i_color *trans);
 void i_copy        (i_img *im,i_img *src);
-int i_rubthru     (i_img *im,i_img *src,int tx,int ty);
+int  i_rubthru     (i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny, int src_maxx, int src_maxy);
+
 
 undef_int i_flipxy (i_img *im, int direction);
 extern i_img *i_rotate90(i_img *im, int degrees);
index f790fa7..46ccaeb 100644 (file)
@@ -18,7 +18,10 @@ Imager::Transformations - Simple transformations of one image into another.
 
   $dest->paste(left=>40,top=>20,img=>$logo);
 
-  $img->rubthrough(src=>$srcimage,tx=>30,ty=>50);
+  $img->rubthrough(src=>$srcimage,tx=>30, ty=>50);
+  $img->rubthrough(src=>$srcimage,tx=>30, ty=>50,
+                   src_minx=>20, src_miny=>30,
+                   src_maxx=>20, src_maxy=>30);
 
 
   $img->flip(dir=>"h");       # horizontal flip
@@ -167,12 +170,17 @@ A more complicated way of blending images is where one image is
 put 'over' the other with a certain amount of opaqueness.  The
 method that does this is rubthrough.
 
-  $img->rubthrough(src=>$srcimage,tx=>30,ty=>50);
-
-That will take the image C<$srcimage> and overlay it with the upper
-left corner at (30,50).  You can rub 2 or 4 channel images onto a 3
-channel image, or a 2 channel image onto a 1 channel image.  The last
-channel is used as an alpha channel.
+  $img->rubthrough(src=>$overlay,
+                   tx=>30,       ty=>50,
+                   src_minx=>20, src_miny=>30,
+                   src_maxx=>20, src_maxy=>30);
+
+That will take the sub image defined by I<$overlay> and
+I<[src_minx,src_maxx)[src_miny,src_maxy)> and overlay it on top of
+I<$img> with the upper left corner at (30,50).  You can rub 2 or 4
+channel images onto a 3 channel image, or a 2 channel image onto a 1
+channel image.  The last channel is used as an alpha channel.  To add
+an alpha channel to an image see I<convert()>.
 
 
 =item flip
index 7c62a77..3b37b3e 100644 (file)
@@ -7,12 +7,15 @@ $loaded = 1;
 print "ok 1\n";
 init_log("testout/t69rubthru.log", 1);
 
+my $src_height = 80;
+my $src_width = 80;
+
 # raw interface
 my $targ = Imager::ImgRaw::new(100, 100, 3);
-my $src = Imager::ImgRaw::new(80, 80, 4);
+my $src = Imager::ImgRaw::new($src_height, $src_width, 4);
 my $halfred = NC(255, 0, 0, 128);
 i_box_filled($src, 20, 20, 60, 60, $halfred);
-i_rubthru($targ, $src, 10, 10) or print "not ";
+i_rubthru($targ, $src, 10, 10, 0, 0, $src_width, $src_height) or print "not ";
 print "ok 2\n";
 my $c = Imager::i_get_pixel($targ, 10, 10) or print "not ";
 print "ok 3\n";
@@ -26,10 +29,10 @@ print "ok 6\n";
 my $black = NC(0, 0, 0);
 # reset the target and try a grey+alpha source
 i_box_filled($targ, 0, 0, 100, 100, $black);
-my $gsrc = Imager::ImgRaw::new(80, 80, 2);
+my $gsrc = Imager::ImgRaw::new($src_width, $src_height, 2);
 my $halfwhite = NC(255, 128, 0);
 i_box_filled($gsrc, 20, 20, 60, 60, $halfwhite);
-i_rubthru($targ, $gsrc, 10, 10) or print "not ";
+i_rubthru($targ, $gsrc, 10, 10, 0, 0, $src_width, $src_height) or print "not ";
 print "ok 7\n";
 $c = Imager::i_get_pixel($targ, 15, 15) or print "not ";
 print "ok 8\n";
@@ -42,7 +45,7 @@ print "ok 11\n";
 
 # try grey target and grey alpha source
 my $gtarg = Imager::ImgRaw::new(100, 100, 1);
-i_rubthru($gtarg, $gsrc, 10, 10) or print "not ";
+i_rubthru($gtarg, $gsrc, 10, 10, 0, 0, $src_width, $src_height) or print "not ";
 print "ok 12\n";
 $c = Imager::i_get_pixel($gtarg, 10, 10) or print "not ";
 print "ok 13\n";
@@ -52,12 +55,12 @@ print "ok 14\n";
 print "ok 15\n";
 
 # an attempt rub a 4 channel image over 1 channel should fail
-i_rubthru($gtarg, $src, 10, 10) and print "not ";
+i_rubthru($gtarg, $src, 10, 10, 0, 0, $src_width, $src_height) and print "not ";
 print "ok 16\n";
 
 # simple test for 16-bit/sample images
 my $targ16 = Imager::i_img_16_new(100, 100, 3);
-i_rubthru($targ16, $src, 10, 10) or print "not ";
+i_rubthru($targ16, $src, 10, 10, 0, 0, $src_width, $src_height) or print "not ";
 print "ok 17\n";
 $c = Imager::i_get_pixel($targ16, 30, 30) or print "not ";
 print "ok 18\n";
@@ -67,7 +70,7 @@ print "ok 19\n";
 # check the OO interface
 my $ootarg = Imager->new(xsize=>100, ysize=>100);
 my $oosrc = Imager->new(xsize=>80, ysize=>80, channels=>4);
-$oosrc->box(color=>$halfred, xmin=>20, ymin=>20, xmax=>60, ymax=>60, 
+$oosrc->box(color=>$halfred, xmin=>20, ymin=>20, xmax=>60, ymax=>60,
             filled=>1);
 $ootarg->rubthrough(src=>$oosrc, tx=>10, ty=>10) or print "not ";
 print "ok 20\n";