Skip to content

Instantly share code, notes, and snippets.

@pablosun
Created April 13, 2018 08:28
Show Gist options
  • Save pablosun/62ff0b10368a682c28fc881b0b974710 to your computer and use it in GitHub Desktop.
Save pablosun/62ff0b10368a682c28fc881b0b974710 to your computer and use it in GitHub Desktop.
Reads a png file and convert it to planar raw byte file.
#!/usr/bin/env python
'''
Reads a png file and convert it to planar raw byte file.
Requires Python3 and pypng.
Please use
```
#pip install pypng
```
to install the required png library.
'''
import sys
import png
import os
import itertools
if __name__ == "__main__":
if len(sys.argv) < 2:
print(r'usage: "py -3 png_to_channel_maps.py input.png"')
OUTPUT_FN = r"output.bin" if len(sys.argv) < 3 else sys.argv[2]
with open(sys.argv[1], "rb") as f:
with open(OUTPUT_FN, "wb") as o:
png = png.Reader(file = f)
(width, height, frame_data, meta) = png.asRGB8()
print("width, height = %d, %d" % (width, height))
'''
the format is boxed row, flat pixel
list([ (R,G,B), (R,G,B), (R,G,B) ],
[ (R,G,B), (R,G,B), (R,G,B) ],
...)
'''
# for each channel (r, g, b)
channelNum = 3
for c in (0, 1, 2):
# note that frame_data is a generator -
# so we "clone" the generator before iterating through it.
frame_data, frame_data_copy = itertools.tee(frame_data)
for row in frame_data_copy:
# skipping channels
for pixel_value in row[c::channelNum]:
o.write(pixel_value.to_bytes(1, 'little'))
print("expected size = %d" % (width * height * channelNum,))
# f and o auto-closes.
print("resulting file '%s' size = %d" % (OUTPUT_FN, os.path.getsize(OUTPUT_FN)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment