"""
Example code integrating RGB PNG files, PyPNG and NumPy
(abstracted from Mel Raab's functioning code)
"""
import numpy
import png
import pngsuite
"""
Reading from PNG file into numpy array.
If you have a PNG file for an RGB image,
and want to create a numpy array of data from it.
"""
pngReader = png.Reader(bytes=pngsuite.basn2c16)
row_count, column_count, pngdata, meta = pngReader.asDirect()
bitdepth = meta["bitdepth"]
plane_count = meta["planes"]
assert plane_count == 3
""" Boxed row flat pixel:
list([R,G,B, R,G,B, R,G,B],
[R,G,B, R,G,B, R,G,B])
Array dimensions for this example: (2,9)
Create `image_2d` as a two-dimensional NumPy array by
stacking a sequence of 1-dimensional arrays (rows).
The NumPy array is a sequence of rows, which is ideal for PyPNG;
it will have dimensions ``(row_count,column_count*plane_count)``.
"""
image_2d = numpy.vstack(map(numpy.uint16, pngdata))
del pngReader
del pngdata
""" Reconfigure for easier referencing, similar to:
list([ (R,G,B), (R,G,B), (R,G,B) ],
[ (R,G,B), (R,G,B), (R,G,B) ])
Array dimensions for this example: (2,3,3)
``image_3d`` will contain the image as a three-dimensional numpy
array, having dimensions ``(row_count,column_count,plane_count)``.
"""
image_3d = numpy.reshape(image_2d, (row_count, column_count, plane_count))
""" ============= """
""" Convert NumPy image_3d array to PNG image file.
If the data is three-dimensional, as it is above,
the best thing to do is reshape it into a two-dimensional array with
a shape of ``(row_count, column_count*plane_count)``.
Because a two-dimensional numpy array is an iterator, it
can be passed directly to the ``png.Writer.write`` method.
"""
row_count, column_count, plane_count = image_3d.shape
assert plane_count == 3
with open("picture_out.png", "wb") as out:
pngWriter = png.Writer(
column_count, row_count, greyscale=False, alpha=False, bitdepth=16
)
image_2d = numpy.reshape(image_3d, (-1, column_count * plane_count))
pngWriter.write(out, image_2d)