from math import floor, ceil

bgcolor = 0

def in_image(image, x, y):
    return x >= 0 and y >= 0 and x < image.shape[0] and y < image.shape[1]

def pv(image, x, y, method):
    if method == 'nearest':
        x, y = round(x), round(y)

        return image[round(x)][round(y)] if in_image(image, x, y) else bgcolor

    if method == 'linear':
        x1, y1 = floor(x), floor(y)
        x2, y2 = floor(x + 1), floor(y + 1)

        if not in_image(image, x1, y1) or not in_image(image, x2, y2):
            return bgcolor

        diff = (x2 - x1) * (y2 - y1)

        return image[x1][y1] / diff * (x2 - x) * (y2 - y) \
            + image[x2][y1] / diff * (x - x1) * (y2 - y) \
            + image[x1][y2] / diff * (x2 - x) * (y - y1) \
            + image[x2][y2] / diff * (x - x1) * (y - y1)

    raise ValueError, 'Interpolation method "%s" is not supported' % method

if __name__ == '__main__':
    from pylab import linspace, show, imread, plot, array

    def profile(image, x0, y0, x1, y1, n, method):
        """Profile of an image along line in n points."""
        dataset = zip(linspace(x0, x1, n), linspace(y0, y1, n))
        return array([pv(image, x, y, method) for x, y in dataset])

    a = imread('cameraman.png')
    for method in ['nearest', 'linear']:
        plot(profile(a, 100, 100, 120, 120, 20, method))
    show()
