chh
chh

Reputation: 167

Mirror an image using Python

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?

Upvotes: 2

Views: 7354

Answers (2)

emptybrother7
emptybrother7

Reputation: 1

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') 

Upvotes: 0

gpoo
gpoo

Reputation: 8638

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

Upvotes: 2

Related Questions