简体   繁体   中英

Creating and combining numerous images in Python - Error: Too many open files:

So basically I've got 2 codes:

  1. One creates a number of different coloured images with 1 pixel dimensions

  2. 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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM