On Tue, 20 Jan 2009 11:49:02 +1100
[email protected] wrote:

| On Mon, Jan 19, 2009 at 02:24:50PM +1000, Anthony Thyssen wrote:
| > > What I'd like to be able to do is to only average parts of images that are
| > > not transparent.
| ..
| 
| > Do what everyone else does,  mask the resulting images with the
| > original using DstIn operators  (mask using the transparency shape given)
| 
| I can see how that would work for averaging two images but not for an
| arbitrary number.  Say I had four images, possible overlaps are:
| 
| 1  2  3  4                    # no overlap, no average 
| 1+2  1+3  1+4  2+3  2+4  3+4  # sum channels and divide by two
| 1+2+3  1+2+4  2+3+4           # sum channels and divide by three
| 1+2+3+4                       # sum channels and divide by four
| 
| I can't see how to generalise this with masking but I'm not practised at image
| manipulation.
| 
| 
| I've tried using PerlMagick to handle pixel data myself
| 
| reading in for each image, for each pixel:
| 
|     my $idx = $j*$height +$i;  # index into data array
|     my @pixel = $im->GetPixel( x=>$i, y=>$j, channel=>'All' );
|     my $opacity_weighting = 1 - $pixel[3];
|     $data[$idx][0] += $pixel[0] * $opacity_weighting;
|     $data[$idx][1] += $pixel[1] * $opacity_weighting;
|     $data[$idx][2] += $pixel[2] * $opacity_weighting;
|     $data[$idx][3] += $pixel[3];
|     $data[$idx][4] += 1 unless $pixel[3] == 1;
| 
| 
| writing out for each pixel:
| 
|     my $idx = $j*$height + $i;  # index into data array
|     my $image_cnt = $data[$idx][4];
|     my $image_total = scalar @images_in;
|     my @pixel = (0,0,0,1);
|     $pixel[0] = $data[$idx][0] / $image_cnt if $image_cnt;
|     $pixel[1] = $data[$idx][1] / $image_cnt if $image_cnt;
|     $pixel[2] = $data[$idx][2] / $image_cnt if $image_cnt;
|     $pixel[3] = $data[$idx][3] / $image_total;
|     $image_out->SetPixel(x=>$i,y=>$j,channel=>'All',color=>\...@pixel);
| 
| And this seems to work but I lose my transparency...
| 
| > Average like most mathematicaly operators do not define what they should
| > do with regards to transparency!
| 
| 
Perhaps -average should be modified to do this.

Note that the IM source is open, and the existing code relativally easy
to follow.  It's not like you have to design it from scratch!

Look at the source file  "magick/image.c"  in the SVN or TAR source download
and check out the function  AverageImages()

Most of the functions complexity can be ignored as it is for Multiple
Processor threading,  concentrate on the inner loop.

=======8<--------
      for (x=0; x < (long) next->columns; x++)
      {
        SetMagickPixelPacket(next,p,indexes+x,&pixel);
        average_pixel[x].red+=QuantumScale*pixel.red;
        average_pixel[x].green+=QuantumScale*pixel.green;
        average_pixel[x].blue+=QuantumScale*pixel.blue;
        average_pixel[x].opacity+=QuantumScale*pixel.opacity;
        if (average_image->colorspace == CMYKColorspace)
          average_pixel[x].index+=QuantumScale*pixel.index;
        p++;
      }
      image_view=DestroyCacheView(image_view);
      next=GetNextImageInList(next);
    }
=======8<--------

Should be easy to modify to understand transparency!

You can also look at simular code in resize, blur, and gaussian
all of which do simular weighted pixal averaging.

If you like to know about generating test builds (without installing)
let me know.   


  Anthony Thyssen ( System Programmer )    <[email protected]>
 -----------------------------------------------------------------------------
  My french isn't %...@#$%^&* good either...  pardon my french ;-)
                                                  -- Anthony Thyssen
 -----------------------------------------------------------------------------
     Anthony's Home is his Castle     http://www.cit.gu.edu.au/~anthony/

_______________________________________________
Magick-users mailing list
[email protected]
http://studio.imagemagick.org/mailman/listinfo/magick-users

Reply via email to