Using Python 3.x to properly read ppm files

2019-09-09 16:54发布

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.

1条回答
Luminary・发光体
2楼-- · 2019-09-09 17:14

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')]
查看更多
登录 后发表回答