The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Image::Leptonica::Func::rotate

VERSION

version 0.04

rotate.c

rotate.c

   General rotation about image center
            PIX     *pixRotate()
            PIX     *pixEmbedForRotation()

   General rotation by sampling
            PIX     *pixRotateBySampling()

   Nice (slow) rotation of 1 bpp image
            PIX     *pixRotateBinaryNice()

   Rotation including alpha (blend) component
            PIX     *pixRotateWithAlpha()

   Rotations are measured in radians; clockwise is positive.

   The general rotation pixRotate() does the best job for
   rotating about the image center.  For 1 bpp, it uses shear;
   for others, it uses either shear or area mapping.
   If requested, it expands the output image so that no pixels are lost
   in the rotation, and this can be done on multiple successive shears
   without expanding beyond the maximum necessary size.

FUNCTIONS

pixEmbedForRotation

PIX * pixEmbedForRotation ( PIX *pixs, l_float32 angle, l_int32 incolor, l_int32 width, l_int32 height )

pixEmbedForRotation()

    Input:  pixs (1, 2, 4, 8, 32 bpp rgb)
            angle (radians; clockwise is positive)
            incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
            width (original width; use 0 to avoid embedding)
            height (original height; use 0 to avoid embedding)
    Return: pixd, or null on error

Notes:
    (1) For very small rotations, just return a clone.
    (2) Generate larger image to embed pixs if necessary, and
        place the center of the input image in the center.
    (3) Rotation brings either white or black pixels in
        from outside the image.  For colormapped images where
        there is no white or black, a new color is added if
        possible for these pixels; otherwise, either the
        lightest or darkest color is used.  In most cases,
        the colormap will be removed prior to rotation.
    (4) The dest is to be expanded so that no image pixels
        are lost after rotation.  Input of the original width
        and height allows the expansion to stop at the maximum
        required size, which is a square with side equal to
        sqrt(w*w + h*h).
    (5) For an arbitrary angle, the expansion can be found by
        considering the UL and UR corners.  As the image is
        rotated, these move in an arc centered at the center of
        the image.  Normalize to a unit circle by dividing by half
        the image diagonal.  After a rotation of T radians, the UL
        and UR corners are at points T radians along the unit
        circle.  Compute the x and y coordinates of both these
        points and take the max of absolute values; these represent
        the half width and half height of the containing rectangle.
        The arithmetic is done using formulas for sin(a+b) and cos(a+b),
        where b = T.  For the UR corner, sin(a) = h/d and cos(a) = w/d.
        For the UL corner, replace a by (pi - a), and you have
        sin(pi - a) = h/d, cos(pi - a) = -w/d.  The equations
        given below follow directly.

pixRotate

PIX * pixRotate ( PIX *pixs, l_float32 angle, l_int32 type, l_int32 incolor, l_int32 width, l_int32 height )

pixRotate()

    Input:  pixs (1, 2, 4, 8, 32 bpp rgb)
            angle (radians; clockwise is positive)
            type (L_ROTATE_AREA_MAP, L_ROTATE_SHEAR, L_ROTATE_SAMPLING)
            incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
            width (original width; use 0 to avoid embedding)
            height (original height; use 0 to avoid embedding)
    Return: pixd, or null on error

Notes:
    (1) This is a high-level, simple interface for rotating images
        about their center.
    (2) For very small rotations, just return a clone.
    (3) Rotation brings either white or black pixels in
        from outside the image.
    (4) The rotation type is adjusted if necessary for the image
        depth and size of rotation angle.  For 1 bpp images, we
        rotate either by shear or sampling.
    (5) Colormaps are removed for rotation by area mapping.
    (6) The dest can be expanded so that no image pixels
        are lost.  To invoke expansion, input the original
        width and height.  For repeated rotation, use of the
        original width and height allows the expansion to
        stop at the maximum required size, which is a square
        with side = sqrt(w*w + h*h).

*** Warning: implicit assumption about RGB component ordering 

pixRotateBinaryNice

PIX * pixRotateBinaryNice ( PIX *pixs, l_float32 angle, l_int32 incolor )

pixRotateBinaryNice()

    Input:  pixs (1 bpp)
            angle (radians; clockwise is positive; about the center)
            incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
    Return: pixd, or null on error

Notes:
    (1) For very small rotations, just return a clone.
    (2) This does a computationally expensive rotation of 1 bpp images.
        The fastest rotators (using shears or subsampling) leave
        visible horizontal and vertical shear lines across which
        the image shear changes by one pixel.  To ameliorate the
        visual effect one can introduce random dithering.  One
        way to do this in a not-too-random fashion is given here.
        We convert to 8 bpp, do a very small blur, rotate using
        linear interpolation (same as area mapping), do a
        small amount of sharpening to compensate for the initial
        blur, and threshold back to binary.  The shear lines
        are magically removed.
    (3) This operation is about 5x slower than rotation by sampling.

pixRotateBySampling

PIX * pixRotateBySampling ( PIX *pixs, l_int32 xcen, l_int32 ycen, l_float32 angle, l_int32 incolor )

pixRotateBySampling()

    Input:  pixs (1, 2, 4, 8, 16, 32 bpp rgb; can be cmapped)
            xcen (x value of center of rotation)
            ycen (y value of center of rotation)
            angle (radians; clockwise is positive)
            incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
    Return: pixd, or null on error

Notes:
    (1) For very small rotations, just return a clone.
    (2) Rotation brings either white or black pixels in
        from outside the image.
    (3) Colormaps are retained.

pixRotateWithAlpha

PIX * pixRotateWithAlpha ( PIX *pixs, l_float32 angle, PIX *pixg, l_float32 fract )

pixRotateWithAlpha()

    Input:  pixs (32 bpp rgb or cmapped)
            angle (radians; clockwise is positive)
            pixg (<optional> 8 bpp, can be null)
            fract (between 0.0 and 1.0, with 0.0 fully transparent
                   and 1.0 fully opaque)
    Return: pixd (32 bpp rgba), or null on error

Notes:
    (1) The alpha channel is transformed separately from pixs,
        and aligns with it, being fully transparent outside the
        boundary of the transformed pixs.  For pixels that are fully
        transparent, a blending function like pixBlendWithGrayMask()
        will give zero weight to corresponding pixels in pixs.
    (2) Rotation is about the center of the image; for very small
        rotations, just return a clone.  The dest is automatically
        expanded so that no image pixels are lost.
    (3) Rotation is by area mapping.  It doesn't matter what
        color is brought in because the alpha channel will
        be transparent (black) there.
    (4) If pixg is NULL, it is generated as an alpha layer that is
        partially opaque, using @fract.  Otherwise, it is cropped
        to pixs if required and @fract is ignored.  The alpha
        channel in pixs is never used.
    (4) Colormaps are removed to 32 bpp.
    (5) The default setting for the border values in the alpha channel
        is 0 (transparent) for the outermost ring of pixels and
        (0.5 * fract * 255) for the second ring.  When blended over
        a second image, this
        (a) shrinks the visible image to make a clean overlap edge
            with an image below, and
        (b) softens the edges by weakening the aliasing there.
        Use l_setAlphaMaskBorder() to change these values.
    (6) A subtle use of gamma correction is to remove gamma correction
        before rotation and restore it afterwards.  This is done
        by sandwiching this function between a gamma/inverse-gamma
        photometric transform:
            pixt = pixGammaTRCWithAlpha(NULL, pixs, 1.0 / gamma, 0, 255);
            pixd = pixRotateWithAlpha(pixt, angle, NULL, fract);
            pixGammaTRCWithAlpha(pixd, pixd, gamma, 0, 255);
            pixDestroy(&pixt);
        This has the side-effect of producing artifacts in the very
        dark regions.

*** Warning: implicit assumption about RGB component ordering 

AUTHOR

Zakariyya Mughal <zmughal@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by Zakariyya Mughal.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.