0

I am trying to read in data from a file, say:

    P3
    400 200
    255
    255 255 255
    0 255
    0
    0 0 0

And I need to account for the first 4 numbers not being pixel data but important information for the creation of the image. I have written the code below, but I'm not sure how to properly take the first 4 numbers, use them for a different part of my program, and then read the rest of the image data.

somebody
  • 85
  • 3
  • 10
  • How exactly is this question different from your [previous two questions](http://stackoverflow.com/questions/22925649/reading-tokens-from-a-file-in-python-3-x) [on this topic](http://stackoverflow.com/questions/22926241/reading-input-from-a-file-in-python-3-x)? If you're not getting the answers you need, you probably need to clarify your questions more, rather than just asking again with a slightly different wordings. For instance, [my answer over here](http://stackoverflow.com/a/22944337/1405065) can surely be adapted to grab 4 special tokens instead of just one, if that's what you need. – Blckknght Apr 08 '14 at 20:03
  • Because now I am not focused on how to read in from the file one token at a time, I have figured that out. Now I am trying to figure out how to collect 4 of them, and then assign them to different variables. I am not trying to figure out the best way to read the pixel values in anymore. If I can clarify my question more please let me know. I'm just not sure how to adapt what I have to treat the first 4 values specially. In response to your answer, I am new to programming and am unfamiliar with the zip function or how to manipulate it. – somebody Apr 08 '14 at 21:00
  • In addition, these files will be massive so grabbing just the whole thing as a string would become very cumbersome. I understand your abilities far surpass mine, but I have spent hours and haven't been able to come up with a simple way to treat the first 4 tokens as something in itself. – somebody Apr 08 '14 at 21:12
  • How big are your images? I wrote something in Python just a few months ago that took in an entire 720x540 PPM image as a string and it wasn't enough to even slow it down. That's without taking any special care in the code, just using normal operations (`str.split`, using `list`s, etc.). Are you on a really show machine for some reason? – Two-Bit Alchemist Apr 08 '14 at 23:50

1 Answers1

1

You're micro-optimizing. Reading an entire PPM image into a string is not "very cumbersome". As it turns out, I have a 720x540 PPM lying around, so I opened it up with Python:

Python 3.4.0 (default, Mar 17 2014, 23:20:09) 
[GCC 4.8.2 20140206 (prerelease)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> with open('ppm/cake.ppm', 'r') as ppm:
...   data = ppm.read()
... 

Since I called read with no argument, data now contains the entire image as a string. Note these commands execute instantaneously as usual. There is no noticeable slowdown. I can perform normal operations on them:

>>> values = data.split()
>>> values[0]
'P3'
>>> values[1]
'720'
>>> values[2]
'540'
>>> values[3]
'255'

So you can see it is a P3-encoded PPM, 720px high, 540px wide. Note that value[3:] now contains just the color information (not the header).

Even if I double the amount of information I get no performance degradation or lag, without taking any special precautions:

>>> values += values[3:]
>>> len(values)
2332805

There's all kinds of things you can do to handle even larger data than this in Python (using generators, for example), and this code handles the same for me on two desktops (of vastly different ages and hardware configurations), a modern laptop, and a virtual machine. In short, you don't need to worry about such precautions. Just do things the easy way and get on to doing something cool with your PPM image. :)

EDIT:

Hey, look, I did find something that takes a second. A second.

>>> encoding, height, width, *values = data.split()
>>> rgb = [tuple(values[i:i+3]) for i in range(0, len(values), 3)]
>>> rgb[:10]
[('255', '123', '125'), ('124', '124', '126'), ('125', '127', '129'), ('128', '129', '131'), ('130', '128', '130'), ('129', '126', '128'), ('127', '132', '134'), ('133', '132', '135'), ('134', '135', '140'), ('139', '137', '143')]
Two-Bit Alchemist
  • 17,966
  • 6
  • 47
  • 82