1

I'm writing a program to create a RGB graph of an equation by iterating through x and y as variables. I will be generating images as large as 65536x65536 (which is 12GB uncompressed). This is my current code:

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

I've tried using PIL to write the image, but it tries to create the whole image in RAM. Since I don't have 12GB available RAM, Python crashes. Is there library I can use to write to the image incrementally, without loading it all in RAM?

Something like this?

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)
LostXOR
  • 197
  • 13
  • Would a solution be breaking the image into multiple sub images? You could name them with a position such as `image_Xpos_Ypos.bmp` or does it have to be a single image? – GTBebbo Apr 16 '20 at 14:10
  • I'd prefer it's a single image. – LostXOR Apr 16 '20 at 14:24
  • I believe if you open the file in `append` mode it won't load the file into RAM, just write to the HD. However, you may have to close and reopen the file to free memory from RAM that may be save from the writing process. – GTBebbo Apr 16 '20 at 14:28
  • How would I do that? – LostXOR Apr 17 '20 at 15:02
  • 1
    [Appending to a file in python](https://stackoverflow.com/questions/4706499/how-do-you-append-to-a-file-in-python). And to intermittently close the file, you would have to count lines written until they reach a threshold then reopen the file and continue writing (appending). – GTBebbo Apr 17 '20 at 16:57
  • I meant how would I write the image to the file using `append`? – LostXOR Apr 23 '20 at 17:43

0 Answers0