|
NAMEImager::Engines - Programmable transformation operationsSYNOPSISuse Imager; my %opts; my @imgs; my $img; ... my $newimg = $img->transform( xexpr=>'x', yexpr=>'y+10*sin((x+y)/10)') or die $img->errstr; my $newimg = Imager::transform2(\%opts, @imgs) or die "transform2 failed: $Imager::ERRSTR"; my $newimg = $img->matrix_transform( matrix=>[ -1, 0, $img->getwidth-1, 0, 1, 0, 0, 0, 1 ]); DESCRIPTIONtransform()The "transform()" function can be used to generate spatial warps and rotations and such effects. It only operates on a single image and its only function is to displace pixels.It can be given the operations in postfix notation or the module Affix::Infix2Postfix can be used to generate postfix code from infix code. Look in the test case t/t55trans.t for an example. "transform()" needs expressions (or opcodes) that determine the source pixel for each target pixel. Source expressions are infix expressions using any of the +, -, *, / or ** binary operators, the - unary operator, ( and ) for grouping and the "sin()" and "cos()" functions. The target pixel is input as the variables x and y. You specify the x and y expressions as "xexpr" and "yexpr" respectively. You can also specify opcodes directly, but that's magic deep enough that you can look at the source code. Note: You can still use the transform() function, but the transform2() function is just as fast and is more likely to be enhanced and maintained. $new_img=$img->transform(xexpr=>'x',yexpr=>'y+10*sin((x+y)/10)') $new_img=$img->transform(xexpr=>'x+0.1*y+5*sin(y/10.0+1.57)', yexpr=>'y+10*sin((x+y-0.785)/10)') transform2()Imager also supports a "transform2()" class method which allows you perform a more general set of operations, rather than just specifying a spatial transformation as with the transform() method, you can also perform color transformations, image synthesis and image combinations from multiple source images."transform2()" takes an reference to an options hash, and a list of images to operate one (this list may be empty): my %opts; my @imgs; ... my $img = Imager::transform2(\%opts, @imgs) or die "transform2 failed: $Imager::ERRSTR"; The options hash may define a transformation function, and optionally:
The transformation function is specified using either the "expr" or "rpnexpr" member of the options. Infix expressions You can supply infix expressions to transform 2 with the "expr" keyword. $opts{expr} = 'return getp1(w-x, h-y)' The 'expression' supplied follows this general grammar: ( identifier '=' expr ';' )* 'return' expr This allows you to simplify your expressions using variables. A more complex example might be: $opts{expr} = 'pix = getp1(x,y); return if(value(pix)>0.8,pix*0.8,pix)' Currently to use infix expressions you must have the Parse::RecDescent module installed (available from CPAN). There is also what might be a significant delay the first time you run the infix expression parser due to the compilation of the expression grammar. Postfix expressions You can supply postfix or reverse-polish notation expressions to transform2() through the "rpnexpr" keyword. The parser for "rpnexpr" emulates a stack machine, so operators will expect to see their parameters on top of the stack. A stack machine isn't actually used during the image transformation itself. You can store the value at the top of the stack in a variable called "foo" using "!foo" and retrieve that value again using @foo. The !foo notation will pop the value from the stack. An example equivalent to the infix expression above: $opts{rpnexpr} = 'x y getp1 !pix @pix value 0.8 gt @pix 0.8 * @pix ifp' At the end of the expression there should be a single pixel value left on the stack, which is used as the output pixel. Operators transform2() has a fairly rich range of operators. Each entry below includes the usage with "rpnexpr", formatted as: operand operand ...
operator -- result
If the operand or result begins with "N" it is a numeric value, if it begins with "C" it is a color or pixel value.
N1 N2 + -- N
N1 N2 * -- N N1 N2 - -- N N1 N2 / -- N N1 N2 ** -- N N1 uminus -- N
N sin -- N
N cos -- N Ny Nx atan2 -- N
Nx1 Ny1 Nx2 Ny2
distance -- N
N sqrt -- N
N abs -- N
Nx Ny getp1 -- C
Nx Ny getp2 -- C Nx Ny getp3 -- C
C value -- N
C hue -- N C sat -- N Nh Ns Nv hsv -- C Nh Ns Nv Na hsva -- C
C red -- N
C green -- N C blue -- N Nr Ng Nb rgb -- C Nr Ng Nb Na rgba -- C
C alpha -- N
N int -- N
Ncond N-true-result N-false-result
if -- N
Ncond C-true-result C-false-result if -- C Ncond C-true-result C-false-result ifp -- C
N1 N2 <= -- N
N1 N2 < -- N N1 N2 >= -- N N1 N2 > -- N N1 N2 == -- N N1 N2 != -- N
N1 N2 and -- N
N1 N2 or -- N N not -- N
N log -- N
N exp -- N
Na Nb Nc Nd det --
N
Constants transform2() defines the following constants:
A few examples: rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat x y getp1 !pix @pix sat 0.7 gt @pat @pix ifp' tiles a smaller version of the input image over itself
where the color has a saturation over 0.7.
rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat y 360 / !rat x y getp1 1 @rat - pmult @pat @rat pmult padd' tiles the input image over itself so that at the top of the image the full-size image is at full strength and at the bottom the tiling is most visible. rpnexpr=>'x y getp1 !pix @pix value 0.96 gt @pix sat 0.1 lt and 128 128 255 rgb @pix ifp' replace pixels that are white or almost white with a palish blue rpnexpr=>'x 35 % 10 * y 45 % 8 * getp1 !pat x y getp1 !pix @pix sat 0.2 lt @pix value 0.9 gt and @pix @pat @pix value 2 / 0.5 + pmult ifp' Tiles the input image over it self where the image isn't white or almost white. rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a2 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv' Produces a spiral. rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv' A spiral built on top of a color wheel. For details on expression parsing see Imager::Expr. For details on the virtual machine used to transform the images, see Imager::regmach. # generate a colorful spiral # requires that Parse::RecDescent be installed my $newimg = Imager::transform2({ width => 160, height=>160, expr => <<EOS dist = distance(x, y, w/2, h/2); angle = atan2(y-h/2, x-w/2); angle2 = (dist / 10 + angle) % ( 2 * pi ); return hsv(angle*180/pi, 1, (sin(angle2)+1)/2); EOS }); # replace green portions of an image with another image my $newimg = Imager::transform2({ rpnexpr => <<EOS x y getp2 !pat # used to replace green portions x y getp1 !pix # source with "green screen" @pix red 10 lt @pix blue 10 lt && # low blue and red @pix green 254 gt && # and high green @pat @pix ifp EOS }, $source, $background); Matrix Transformations
AUTHORTony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson
Visit the GSP FreeBSD Man Page Interface. |