Создать очень большое изображение постепенно? - PullRequest
1 голос
/ 16 апреля 2020

Я пишу программу для создания RGB-графика уравнения путем итерации x и y в качестве переменных. Я буду генерировать изображения размером 65536x65536 (что составляет 12 ГБ без сжатия). Это мой текущий код:

from struct import pack, unpack

#Graph attributes
graphSize = [1024, 1024]
graphCenter = [0, 0]
graphMultiplier = 1
equation = "x * y"
dataPath = "data.txt"
imagePath = "image.png"

#Compile graph equation
code = compile(equation, "equation", "eval")

#Calculate graph corners
graphCorners = [
    [int(graphCenter[0] - graphSize[0] / 2 - 1),
     int(graphCenter[0] + graphSize[0] / 2)],
    [int(graphCenter[1] - graphSize[1] / 2 - 1),
     int(graphCenter[1] + graphSize[1] / 2)]
]

#Open data file
dataFile = open(dataPath, "wb")

#Iterate through graph
for y in range(graphCorners[1][0], graphCorners[1][1]):
    for x in range(graphCorners[0][0], graphCorners[0][1]):
        #Try to calculate value
        try:
            number = eval(code, {"x" : x, "y" : y}) * graphMultiplier
        except:
            number = 0

        #Pack number into data file
        dataFile.write(pack("d", number))

dataFile.close()


dataFile = open(dataPath, "rb")

#Iterate through data file
for n in range(graphSize[0] * graphSize[1]):
    #Get number
    number = unpack("d", dataFile.read(8))[0]

    #Convert to RGB
    rgb = [int(number % 256),
           int(number // 256 % 256),
           int(number // 65536 % 256)]

    writePixelToImage(imagePath, rgb) #Example code that doesn't do anything

Я пытался использовать PIL для записи изображения, но он пытается создать все изображение в оперативной памяти. Поскольку у меня нет 12 ГБ доступной оперативной памяти, Python падает. Есть ли библиотека, которую я могу использовать для постепенной записи в изображение, не загружая все это в ОЗУ?

Как-то так?

giantImage = image("rgb", (65536, 65536))
for y in range(0, 65536):
    for x in range(0, 65536):
        rgb = (random(0, 255), random(0, 255), random(0, 255))
        giantImage.write((x, y), rgb)
...