PIL question

T

Tim Eichholz

I'm trying to cut a BMP with 80 adjacent frames down to 40 using the
Image.copy and .paste functions but I'm getting error "ValueError:
images do not match" on the paste line.

Here is the source ---
import sys
from PIL import Image

if len(sys.argv) == 2:
file = sys.argv[1]
else:
print "Usage: python rotate.py image.bmp"
exit

print "Loading image "+file
image = Image.open(file)
if image:
print "Successful"
else:
print "Something didn't work out right."

cols = []

size = image.size
framew = int(raw_input("Frame width: "))
frameh = int(raw_input("Frame height: "))
ncols = size[0]/framew

print str(ncols)+" Columns, "+str(size[1]/frameh)+" Rows\n"

c = 1
while c <= ncols:
cols += [image.crop((framew*c, 0, frameh*(c+1), frameh*(c+1)))]
c += 1

print "New image size "+str(framew*ncols/2)+"x"+str(frameh)
print "Resizing image, could take a minute..."
newimage = image.resize(((framew*(ncols/2)), frameh), Image.NEAREST)
print "Image resized. Starting rotation loop."

f = 0
while f < (framew*(ncols/2)):
if f%2 == 0:
print "Pasting at "+str(f*framew)+"x0 to "+str(f*framew+framew)
+"x192"
newimage.paste(cols[f], (f*framew, 0, (f*framew)+192, 192))
f += 1

newimage.save('NEWIMAGE.BMP')
 
P

Peter Otten

Tim said:
I'm trying to cut a BMP with 80 adjacent frames down to 40 using the
Image.copy and .paste functions but I'm getting error "ValueError:
images do not match" on the paste line.
newimage.paste(cols[f], (f*framew, 0, (f*framew)+192, 192))

The 4-tuple doesn't match the size of the image you are pasting:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 1077, in paste
self.im.paste(im, box)
ValueError: images do not match

You can add

for index, image in enumerate(cols):
print "image %d --> %s" % (index, image.size)
# image.save("tmp%d.png" % index)

to your code to learn the actual size of your intermediate images.
After you have fixed the size problem and see that the resulting image
doesn't meet your expectations (likely, don't despair) you can uncomment the
image.save(...) statement and have a look at the intermediate images.

A hint about counting loops: instead of

x = 0
while x < n:
...
x = x + 1

it is idiomatic python to write

for x in range(n):
...

and

x = 0
while x < total_width:
# ...
x += single_width

is typically expressed as

for x in range(0, total_width, single_width):
...

Have a look at the tutorial for more basic tips.

Peter
 
T

Tim Eichholz

Tim said:
I'm trying to cut a BMP with 80 adjacent frames down to 40 using the
Image.copy and .paste functions but I'm getting error "ValueError:
images do not match" on the paste line.
newimage.paste(cols[f], (f*framew, 0, (f*framew)+192, 192))

The 4-tuple doesn't match the size of the image you are pasting:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/dist-packages/PIL/Image.py", line 1077, in paste
    self.im.paste(im, box)
ValueError: images do not match

You can add

for index, image in enumerate(cols):
   print "image %d --> %s" % (index, image.size)
   # image.save("tmp%d.png" % index)

to your code to learn the actual size of your intermediate images.
After you have fixed the size problem and see that the resulting image
doesn't meet your expectations (likely, don't despair) you can uncomment the
image.save(...) statement and have a look at the intermediate images.

A hint about counting loops: instead of

x = 0
while x < n:
   ...
   x = x + 1

it is idiomatic python to write

for x in range(n):
    ...

and

x = 0
while x < total_width:
    # ...
    x += single_width

is typically expressed as

for x in range(0, total_width, single_width):
   ...

Have a look at the tutorial for more basic tips.

Peter

I think maybe I am using the wrong function. I want to paste the
entire 192x192 contents of cols[f] into newimage. I would think it
works like newimage.paste(cols[f], (x, 0, 192+x, 192)) if that's not
it I think I'm missing a function
 
P

Peter Otten

Tim said:
I think maybe I am using the wrong function. I want to paste the
entire 192x192 contents of cols[f] into newimage. I would think it
works like newimage.paste(cols[f], (x, 0, 192+x, 192)) if that's not
it I think I'm missing a function

Don't "think"! Read the documentation or, if that is hard to understand,
write a tiny script that excercises only the function in question.


I can't test your script because it's not "self-contained" (doesn't run
without user input), but I'm quite certain that the images that you generate
with

c = 1
while c <= ncols:
cols += [image.crop((framew*c, 0, frameh*(c+1), frameh*(c+1)))]
c += 1

are not of the size 192x192. Assuming
.... box = framew*c, 0, frameh*(c+1), frameh*(c+1)
.... print "width =", box[2] - box[0], "height =", box[3] - box[1]
.... c += 1
....
width = 192 height = 384
width = 192 height = 576
width = 192 height = 768

See? You need to redo the maths and go through every step of your script,
throw in some diagnostics code to verify that it does what you expect, and
only then proceed to the next operation.

My hunch is that crop() doesn't do what you want rather than paste(), but to
be sure you'd have to explain in plain English what the final image should
look like.

Peter
 
L

Lie Ryan

Tim said:
I think maybe I am using the wrong function. I want to paste the
entire 192x192 contents of cols[f] into newimage. I would think it
works like newimage.paste(cols[f], (x, 0, 192+x, 192)) if that's not
it I think I'm missing a function

Don't "think"!

I hope you don't literally mean that ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top