in reply to Re^2: goo canvas image mask
in thread goo canvas image mask

This is (of necessity due to GDs limitations) a crude vignetting process. Starting with this, you get this.

#! perl -slw use strict; use GD; sub rgba2n { unpack 'N', pack 'C4', pop, @_ } my $src = GD::Image->newFromJpeg( $ARGV[0], 1 ) or die $!; my $dia = $src->width < $src->height ? $src->width : $src->height; my $maxDia = sqrt( $src->width**2 + $src->height**2 ); my $thickness = 10; my $alpha = 127; my $alphaDelta = $thickness * 127 / ( $maxDia - $dia ); $src->setThickness( $thickness ); while ( $dia < $maxDia ) { $src->ellipse( $src->width / 2, $src->height /2, $dia, $dia, rgba2n( 0, 0, 0, $alpha ) ); $alpha -= $alphaDelta; $dia += $thickness; } open PNG, '>:raw', "vigged.png"; print PNG $src->png; close PNG; ## Look at the result; starts default image editor. system 'vigged.png';

The results are crude because GD doesn't support paths or Porter-Duff operations, but the basic idea of using alpha blending of a shape (here thick-walled circles) over an image with an alpha gradient gives an impression of the result.

In theory, you should be able to construct a mask image the same size as the one being vignetted--generally described as the source). You fill this mask image with black, and then draw successively smaller circles (shapes), also in black but gradually reducing the alpha component to 0. The final circle (shape) being the size of the unblended portion of the source that you wish to show through. You then XOR blend the mask with the original image to produce the required output image.

Which should look something like the second image above, but if done using a properly scaled and stroked path, smoother.

If I understand you correctly--no guarantee--what you are hoping for, is for the black in this example to be replaced by pixels from a second source image. In this case, rather than starting with a mask image filled with black, you construct the mask from the second (overlay) image, by drawing your shape successively smaller with reducing alpha as above. But instead drawing the shape in a given color, you draw it such that it only changes the (embedded) alpha component of the existing pixels. I haven't figured out how to do this with GD--or even if it is possible,


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP an inspiration; A true Folk's Guy

Replies are listed 'Best First'.
Re^4: goo canvas image mask
by Corion (Patriarch) on Jul 20, 2010 at 11:01 UTC

    When dealing with more complex image transformations, I usually cheat and construct the image using Inkscape. This gives me an SVG file which I then turn into a template. From these templates I produce more SVG files, which Inkscape then renders into PNG bitmaps.

    This is of course not really fit for running on a server, as firing up the Inkscape process for each image is likely a bit costly, but for my small needs, it provides a quick turnaround.

    Update: Looking at the Inkscape website, I find UniConvertor, which seems to be Inkscape without the UI.