Mirror an image using Python

Question:

I need to flip a picture horizontally, without using the reverse function, I thought I had it right but the returned image is just the bottom right corner of the picture and it is not flipped.

The code I have is

def Flip(image1, image2):
    img = graphics.Image(graphics.Point(0, 0), image1)
    X = img.getWidth()
    Y = img.getHeight()
    for y in range(Y):
        for x in range(X):
            A = img.getPixel(x,y)
            r = A[0]
            g = A[1]
            b = A[2]
            color = graphics.color_rgb(r,g,b)
            img.setPixel(X-x,y,color)
    img = graphics.Image(graphics.Point(0,0), image2)
    win = graphics.GraphWin(image2, img.getWidth(), img.getHeight())
    img.draw(win)

Where did I go wrong?

Asked By: chh

||

Answers:

Here some things that I think could be improved:

def Flip(image1, image2):
    img = graphics.Image(graphics.Point(0, 0), image1)
    X = img.getWidth()
    Y = img.getHeight()
    for y in range(Y):
        for x in range(X):
            A = img.getPixel(x,y)
            r = A[0]
            g = A[1]
            b = A[2]
            color = graphics.color_rgb(r,g,b)

This assignment could be more pythonic:

            r, g, b = img.getPixel(x,y)
            color = graphics.color_rgb(r,g,b)

            img.setPixel(X-x,y,color)

img now has the image half-flipped. This happens because you are writing the content on the same image source, losing the old content anytime until you reach the middle. (Notice that X-x will increase the image size by 1 pixel. If the image width is 100, in the first iteration X-x = 100 - 0 = 100 and because it starts from 0, the image is made wider 1 pixel.) Then, you start copying back. Also, you do not use that content because:

    img = graphics.Image(graphics.Point(0,0), image2)

Here is the problem: you just overwrote the content of img without giving it any use. Later:

    win = graphics.GraphWin(image2, img.getWidth(), img.getHeight())
    img.draw(win)

This seems unrelated with the purpose of the function (flip an image). What I would do is:

import graphics
import sys

def Flip(image_filename):
    img_src = graphics.Image(graphics.Point(0, 0), image_filename)
    img_dst = img_src.clone()
    X, Y = img_src.getWidth(), img_src.getHeight()
    for x in range(X):
        for y in range(Y):
            r, g, b = img_src.getPixel(x, y)
            color = graphics.color_rgb(r, g, b)
            img_dst.setPixel(X-x-1, y, color)

    return img_dst

if __name__ == '__main__':
    input = sys.argv[1] or 'my_image.ppm'
    output = 'mirror-%s' % input
    img = Flip (input)
    img.save(output)

Notices that the function Flip only take care of flipping the image, outside the function you can do whatever you need the image, as you can see in ‘main’ program.

If you want to use only one image, it is possible and more efficient. For that, you can use the same principle for swapping values between variables:

def Flip(image_filename):
    img = graphics.Image(graphics.Point(0, 0), image_filename)
    X, Y = img.getWidth(), img.getHeight()
    for x in range(X/2):
        for y in range(Y):
            r_1, g_1, b_1 = img.getPixel(x, y)
            color_1 = graphics.color_rgb(r_1, g_1, b_1)

            r_2, g_2, b_2 = img.getPixel(X-x-1, y)
            color_2 = graphics.color_rgb(r_2, g_2, b_2)

            img.setPixel(X-x-1, y, color_1)
            img.setPixel(x, y, color_2)

    return img
Answered By: gpoo

I know it has been a long time but you can try this!

from PIL import Image

Image.open('img.png') 

img = Image.open('img.png') 
Mirror_Image=img.transpose(Image.FLIP_LEFT_RIGHT)
Mirror_Image.save(r'imgoutput.png') 
Image.open('imgoutput.png') 
Answered By: emptybrother7
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.