Realign the given image providing the specific horizontal and vertical
    shifts, and crop the image providing the maximum horizontal and
    vertical shifts of images of a same set so that they all have the same
    size.


    @param image: an instance of Python Image Library (PIL) image.

    @param shift_x: horizontal shift in pixels of the image.

    @param shift_y: vertical shift in pixels of the image.

    @param max_shift_x: maximum absolute value of the horizontal shift in
        pixels of the images in the capture.

    @param max_shift_y: maximum absolute value of the vertical shift in
        pixels of the images in the capture.

    @param shift_angle: horizontal displacement angle in degrees of
           the image.

    @param filter: indicate the filter to use when rotating the image.

    @param stretch_factor: coefficient of multiplication to stretch or
           to shrink the image in both horizontal and vertical
           directions.

    @param cropping_box: a 4-tuple defining the left, upper, right, and
           lower pixel coordinate of the rectangular region from the
           specified image.


    @return: a new instance of Python Image Library (PIL) image.

def realign_image(image, shift_x, shift_y, max_shift_x, max_shift_y,
        shift_angle=0.0, filter=Filter.NearestNeighbor,
        stretch_factor=None,
        cropping_box=None):
    """
    Realign the given image providing the specific horizontal and vertical
    shifts, and crop the image providing the maximum horizontal and
    vertical shifts of images of a same set so that they all have the same
    size.


    @param image: an instance of Python Image Library (PIL) image.

    @param shift_x: horizontal shift in pixels of the image.

    @param shift_y: vertical shift in pixels of the image.

    @param max_shift_x: maximum absolute value of the horizontal shift in
        pixels of the images in the capture.

    @param max_shift_y: maximum absolute value of the vertical shift in
        pixels of the images in the capture.

    @param shift_angle: horizontal displacement angle in degrees of
           the image.

    @param filter: indicate the filter to use when rotating the image.

    @param stretch_factor: coefficient of multiplication to stretch or
           to shrink the image in both horizontal and vertical
           directions.

    @param cropping_box: a 4-tuple defining the left, upper, right, and
           lower pixel coordinate of the rectangular region from the
           specified image.


    @return: a new instance of Python Image Library (PIL) image.
    """
    (width, height) = image.size

    # Determine the new size of the image based on the maximal horizontal
    # and vertical shifts of all the other images in this series.
    new_width = width - max_shift_x * 2
    new_height = height - max_shift_y * 2

    # Determine the coordinates of the zone to crop to center the image
    # based on the horizontal and vertical shifts.
    bounding_box_x = (0 if shift_x < 0 else shift_x * 2)
    bounding_box_y = (0 if shift_y < 0 else shift_y * 2)

    if max_shift_x > shift_x:
        bounding_box_width = width - abs(shift_x) * 2
        bounding_box_x += (bounding_box_width - new_width) / 2
        #bounding_box_x = max_shift_x - abs(shift_x)

    if max_shift_y > shift_y:
        bounding_box_height = height - abs(shift_y) * 2
        bounding_box_y += (bounding_box_height - new_height) / 2
        #bounding_box_y = max_shift_y - abs(shift_y)

    # Crop the image and rotate it based on the horizontal displacement
    # angle of this image.
    image = image.crop((bounding_box_x, bounding_box_y,
                        bounding_box_x + new_width, bounding_box_y + new_height)) \
        .rotate(-shift_angle, PIL_FILTER_MAP[filter])

    # Stretch or shrink this image based on its coefficient, keeping the
    # calculated new size of this image.
    if stretch_factor and stretch_factor > 0:
        image = image.resize((int(round(width * stretch_factor)), int(round(height * stretch_factor))),
                             PIL_FILTER_MAP[filter])
        (width, height) = image.size

        if stretch_factor >= 1:
            image = image.crop(((width - new_width) / 2, (height - new_height) / 2,
                                (width - new_width) / 2 + new_width - 1, (height - new_height) / 2 + new_height - 1))
        else:
            _image = Image.new(image.mode, (new_width, new_height))
            _image.paste(image, ((new_width - width) / 2, (new_height - height) / 2))
            image = _image

    # Crop the image to the specified rectangle, if any defined.
    if cropping_box:
        (crop_x1, crop_y1, crop_x2, crop_y2) = cropping_box
        (width, height) = image.size

        image = image.crop(
            (int(round(crop_x1 * width)), int(round(crop_y1 * height)),
             int(round(crop_x2 * width)), int(round(crop_y2 * height))))

    return image