user2711113
user2711113

Reputation: 81

How to horizontally offset odd and even rows of pixels in an image using Python?

I am learning how to use Python for image manipulation and am trying to create an image where odd and even rows of pixels are shifted horizontally by the same amount (e.g. odd rows are shifted 10 pixels to the right and even rows are shifted 10 pixels to the left).

The image consists of a single black word printed on a white background, like this:

http://oi63.tinypic.com/2i255bn.jpg

With the code below, I can get odd and even rows of pixels in two separate images, but I am not sure how to combine them into a single one with 20 pixels total horizontal offset.

from PIL import Image

im = Image.open('myimage.bmp')
print im.size

white = 255,255,255
even = Image.new('RGB',[1024,768], white)

for i in range( im.size[0] ):
    for j in range(im.size[1]):
        if j % 2 == 0 :
            even.putpixel(( int(i), int(j) ), im.getpixel((i,j)) )
even.show()


odd = Image.new('RGB',[1024,768], white)

for i in range( im.size[0] ):
    for j in range(im.size[1]):
        if j % 2 != 0 :
            odd.putpixel(( int(i), int(j) ), im.getpixel((i,j)) )
odd.show()

I am new to Python and I would be really grateful for any help with this!

Upvotes: 0

Views: 2384

Answers (2)

Adam Henderson
Adam Henderson

Reputation: 308

As Rad suggested in the question comments, you only need to create one image and output both the odd and even pixels to their correct positions within it:

from PIL import Image

im = Image.open('myimage.bmp')
print im.size

white = 255,255,255
even = Image.new('RGB',[1024,768], white)

offset = 10

for i in range( im.size[0] ):
    for j in range(im.size[1]):
        x = int(i)+offset
        if j % 2 == 0:
            x = x+10
        else:
            x = x-10    
        even.putpixel(( x, int(j) ), im.getpixel((i,j)) )

even.show()

I added an offset to ensure the pixels don't go off the left of the canvas.

Upvotes: 1

dnalow
dnalow

Reputation: 984

you can use numpy.roll to do the shift:

import numpy as np
import Image
im = Image.open("2i255bn.jpg")
d = im.getdata()

a = np.array(d, dtype=np.uint8).reshape(d.size[::-1]) # make numpy array of data
anew = np.roll(a, 10)
anew[::2] = np.roll(a, -10)[::2]

imnew = Image.fromarray(anew, mode="L")
imnew.show()

this is only valid for the grayscale picture. If you have RGB pictures, the reshape and arguments need to be adapted

Upvotes: 1

Related Questions