def get_tiled_image_dimensions(grid_size, image_size):
    """

    An image consisting of tiles of itself (or same-sized) images
    will be as close to the same dimensions as the original.

    This returns two tuples - the size of the final output image, and the size of the
    tiles that it will consist of.

    :param grid_size: A 2-tuple (width, height) defining the shape of the grid (in number of images)
    :param image_size: A 2-tuple (width, height) defining the shape of the final image (in pixels)
    :return: two 2-tuples, the size of each tile and the size of the final output image/
    """
    tile_width = image_size[0] / grid_size[0]
    # preserve aspect ratio by dividing consistently. grid cols is always >= rows
    tile_height = image_size[1] / grid_size[0]

    # find the final height by multiplying up the tile size by the number of rows.
    final_height = tile_height * grid_size[1]

    return (int(tile_width), int(tile_height)), (int(image_size[0]), int(final_height))