Reputation: 461
So basically I've got 2 codes:
One creates a number of different coloured images with 1 pixel dimensions
The other combines all the created images into one
The first one works perfectly but in the second code I get an error: IOError: [Errno 24] Too many open files: 'Test 3161.png'
The thing is I don't necessarily want to create the files. What I really want is the combined image at the end. I'm not sure how to approach this. Any help would be greatly appreciated.
Code 1 - Creating images
from PIL import Image
import sys
im = Image.new("RGB", (1, 1))
pix = im.load()
j=0
for r in range(65,130):
for g in range(65,130):
for b in range(65,130):
for x in range(1):
for y in range(1):
axis = (r,g,b)
pix[x,y] = axis
print axis
j+=1
im.save('Test {}.png'.format(j), "PNG")
Code 2: Combining images
from PIL import Image
import sys
import glob
imgfiles = []
for file in glob.glob("*.png"):
imgfiles.append(file)
print imgfiles
#stitching images together
images = map(Image.open, imgfiles)
widths, heights = zip(*(i.size for i in images))
total_width = sum(widths)
max_height = max(heights)
new_im = Image.new('RGB', (total_width, max_height))
x_offset = 0
for im in images:
new_im.paste(im, (x_offset,0))
x_offset += im.size[0]
new_im.save('test.png')
This is somewhat the final image I'm trying to get but not with as many colours as shown in it:
The coloured images that are created from code 1 are images that are 1 pixel in width and diameter. For example like this:
Its harder to see as its one pixel right next to this. It looks like a fullstop but is the 1 pixel image in question.
Upvotes: 0
Views: 458
Reputation: 377
To solve the too-many-open-files error, you can make a little function:
def getImageDetails(imgfile):
im = Image.open(imgfile)
size = im.size
im.load() # closes the pointer after it loads the image
return size[0], size[1], im
widths, heights, images = zip(*(getImageDetails(i) for i in imgfiles))
replace these lines with the code above:
images = map(Image.open, imgfiles)
widths, heights = zip(*(i.size for i in images))
Upvotes: 1
Reputation: 207660
I still don't understand what you expect to produce, but this should be close and a lot faster and easier:
#!/usr/local/bin/python3
from PIL import Image
import numpy as np
# Create array to hold output image
result=np.zeros([1,13*13*13,3],dtype=np.uint8)
j=0
for r in range(65,130,5):
for g in range(65,130,5):
for b in range(65,130,5):
result[0,j]= (r,g,b)
j+=1
# Convert output array to image and save
im=Image.fromarray(result)
im.save("result.jpg")
Note that the above script is intended to do the job of both of your scripts in one go.
Note that I made the result image a bit taller (fatter) so you can see it, in fact it is only 1 pixel high.
Note that I added a step of 5 to make the output image smaller because it otherwise exceeds the size limits - for JPEG at least.
Note that I coarsely guessed the array width (13*13*13) on the basis of (130-65)/5, because I don't really understand your requirements.
Upvotes: 1