The png Module¶
-
class
png.
Image
(rows, info)¶ A PNG image. You can create an
Image
object from an array of pixels by callingpng.from_array()
. It can be saved to disk with thesave()
method.Note
The constructor is not public. Please do not call it.
-
save
(file)¶ Save the image to file. If file looks like an open file descriptor then it is used, otherwise it is treated as a filename and a fresh file is opened.
In general, you can only call this method once; after it has been called the first time and the PNG image has been saved, the source data will have been streamed, and cannot be streamed again.
-
-
class
png.
Reader
(_guess=None, **kw)¶ PNG decoder in pure Python.
Create a PNG decoder object.
The constructor expects exactly one keyword argument. If you supply a positional argument instead, it will guess the input type. Choose from the following keyword arguments:
- filename
- Name of input file (a PNG file).
- file
- A file-like object (object with a read() method).
- bytes
bytes
orbytearray
with PNG data.
-
asDirect
()¶ Returns the image data as a direct representation of an
x * y * planes
array. This method is intended to remove the need for callers to deal with palettes and transparency themselves. Images with a palette (colour type 3) are converted to RGB or RGBA; images with transparency (atRNS
chunk) are converted to LA or RGBA as appropriate. When returned in this format the pixel values represent the colour value directly without needing to refer to palettes or transparency information.Like the
read()
method this method returns a 4-tuple:(width, height, pixels, meta)
This method normally returns pixel values with the bit depth they have in the source image, but when the source PNG has an
sBIT
chunk it is inspected and can reduce the bit depth of the result pixels; pixel values will be reduced according to the bit depth specified in thesBIT
chunk (PNG nerds should note a single result bit depth is used for all channels; the maximum of the ones specified in thesBIT
chunk. An RGB565 image will be rescaled to 6-bit RGB666).The meta dictionary that is returned reflects the direct format and not the original source image. For example, an RGB source image with a
tRNS
chunk to represent a transparent colour, will haveplanes=3
andalpha=False
for the source image, but the meta dictionary returned by this method will haveplanes=4
andalpha=True
because an alpha channel is synthesized and added.pixels is the pixel data in boxed row flat pixel format (just like the
read()
method).All the other aspects of the image data are not changed.
-
asFloat
(maxval=1.0)¶ Return image pixels as per
asDirect()
method, but scale all pixel values to be floating point values between 0.0 and maxval.
-
asRGB
()¶ Return image as RGB pixels. RGB colour images are passed through unchanged; greyscales are expanded into RGB triplets (there is a small speed overhead for doing this).
An alpha channel in the source image will raise an exception.
The return values are as for the
read()
method except that the metadata reflect the returned pixels, not the source image. In particular, for this methodmetadata['greyscale']
will beFalse
.
-
asRGB8
()¶ Return the image data as an RGB pixels with 8-bits per sample. This is like the
asRGB()
method except that this method additionally rescales the values so that they are all between 0 and 255 (8-bit). In the case where the source image has a bit depth < 8 the transformation preserves all the information; where the source image has bit depth > 8, then rescaling to 8-bit values loses precision. No dithering is performed. LikeasRGB()
, an alpha channel in the source image will raise an exception.This function returns a 4-tuple: (width, height, pixels, metadata). width, height, metadata are as per the
read()
method.pixels is the pixel data in boxed row flat pixel format.
-
asRGBA
()¶ Return image as RGBA pixels. Greyscales are expanded into RGB triplets; an alpha channel is synthesized if necessary. The return values are as for the
read()
method except that the metadata reflect the returned pixels, not the source image. In particular, for this methodmetadata['greyscale']
will beFalse
, andmetadata['alpha']
will beTrue
.
-
asRGBA8
()¶ Return the image data as RGBA pixels with 8-bits per sample. This method is similar to
asRGB8()
andasRGBA()
: The result pixels have an alpha channel, and values are rescaled to the range 0 to 255. The alpha channel is synthesized if necessary (with a small speed penalty).
-
bytes_to_values
(bs, width=None)¶ Convert a row of bytes into a flat row of values. Result will be a freshly allocated object, not shared with argument.
-
chunk
(lenient=False)¶ Read the next PNG chunk from the input file; returns a (type, data) tuple. type is the chunk’s type as a byte string (all PNG chunk types are 4 bytes long). data is the chunk’s data content, as a byte string.
If the optional lenient argument evaluates to True, checksum failures will raise warnings rather than exceptions.
-
chunklentype
()¶ Reads just enough of the input to determine the next chunk’s length and type, returned as a (length, type) pair where type is a string. If there are no more chunks,
None
is returned.
-
chunks
()¶ Return an iterator that will yield each chunk as a (chunktype, content) pair.
-
deinterlace
(raw)¶ Read raw pixel data, undo filters, deinterlace, and flatten. Return in flat row flat pixel format.
-
iter_bytes_to_values
(byte_rows)¶ Iterator that yields each scanline in boxed row flat pixel format. byte_rows should be an iterator that yields the bytes of each row in turn.
-
iter_straight_byte_rows
(byte_blocks)¶ Iterator that undoes the effect of filtering; yields each row as a sequence of bytes (in serialised format). Assumes input is straightlaced. byte_blocks should be an iterable that yields the raw bytes in blocks of arbitrary size.
-
palette
(alpha='natural')¶ Returns a palette that is a sequence of 3-tuples or 4-tuples, synthesizing it from the
PLTE
andtRNS
chunks. These chunks should have already been processed (for example, by calling thepreamble()
method). All the tuples are the same size: 3-tuples if there is notRNS
chunk, 4-tuples when there is atRNS
chunk.Assumes that the image is colour type 3 and therefore a
PLTE
chunk is required.If the alpha argument is
'force'
then an alpha channel is always added, forcing the result to be a sequence of 4-tuples.
-
preamble
(lenient=False)¶ Extract the image metadata by reading the initial part of the PNG file up to the start of the
IDAT
chunk. All the chunks that precede theIDAT
chunk are read and either processed for metadata or discarded.If the optional lenient argument evaluates to True, checksum failures will raise warnings rather than exceptions.
-
process_chunk
(lenient=False)¶ Process the next chunk and its data. This only processes the following chunk types, all others are ignored:
IHDR
,PLTE
,bKGD
,tRNS
,gAMA
,sBIT
,pHYs
.If the optional lenient argument evaluates to True, checksum failures will raise warnings rather than exceptions.
-
read
(lenient=False)¶ Read the PNG file and decode it. Returns (width, height, pixels, metadata).
May use excessive memory.
pixels are returned in boxed row flat pixel format.
If the optional lenient argument evaluates to True, checksum failures will raise warnings rather than exceptions.
-
read_flat
()¶ Read a PNG file and decode it into flat row flat pixel format. Returns (width, height, pixels, metadata).
May use excessive memory.
pixels are returned in flat row flat pixel format.
See also the
read()
method which returns pixels in the more stream-friendly boxed row flat pixel format.
-
undo_filter
(filter_type, scanline, previous)¶ Undo the filter for a scanline. scanline is a sequence of bytes that does not include the initial filter type byte. previous is decoded previous scanline (for straightlaced images this is the previous pixel row, but for interlaced images, it is the previous scanline in the reduced image, which in general is not the previous pixel row in the final image). When there is no previous scanline (the first row of a straightlaced image, or the first row in one of the passes in an interlaced image), then this argument should be
None
.The scanline will have the effects of filtering removed, and the result will be returned as a fresh sequence of bytes.
-
validate_signature
()¶ If signature (header) has not been read then read and validate it; otherwise do nothing.
-
class
png.
Writer
(width=None, height=None, size=None, greyscale=False, alpha=False, bitdepth=8, palette=None, transparent=None, background=None, gamma=None, compression=None, interlace=False, bytes_per_sample=None, planes=None, colormap=None, maxval=None, chunk_limit=1048576, x_pixels_per_unit=None, y_pixels_per_unit=None, unit_is_meter=False)¶ PNG encoder in pure Python.
Create a PNG encoder object.
Arguments:
- width, height
- Image size in pixels, as two separate arguments.
- size
- Image size (w,h) in pixels, as single argument.
- greyscale
- Input data is greyscale, not RGB.
- alpha
- Input data has alpha channel (RGBA or LA).
- bitdepth
- Bit depth: from 1 to 16 (for each channel).
- palette
- Create a palette for a colour mapped image (colour type 3).
- transparent
- Specify a transparent colour (create a
tRNS
chunk). - background
- Specify a default background colour (create a
bKGD
chunk). - gamma
- Specify a gamma value (create a
gAMA
chunk). - compression
- zlib compression level: 0 (none) to 9 (more compressed); default: -1 or None.
- interlace
- Create an interlaced image.
- chunk_limit
- Write multiple
IDAT
chunks to save memory. - x_pixels_per_unit
- Number of pixels a unit along the x axis (write a pHYs chunk).
- y_pixels_per_unit
- Number of pixels a unit along the y axis (write a pHYs chunk). Along with x_pixel_unit, this gives the pixel size ratio.
- unit_is_meter
- True to indicate that the unit (for the pHYs chunk) is metre.
The image size (in pixels) can be specified either by using the width and height arguments, or with the single size argument. If size is used it should be a pair (width, height).
greyscale and alpha are booleans that specify whether an image is greyscale (or colour), and whether it has an alpha channel (or not).
bitdepth specifies the bit depth of the source pixel values. Each channel may have a different bit depth. Each source pixel must have values that are an integer between 0 and
2**bitdepth-1
, where bitdepth is the bit depth for the corresponding channel. For example, 8-bit images have values between 0 and 255. PNG only stores images with bit depths of 1,2,4,8, or 16 (the same for all channels). When bitdepth is not one of these values or where channels have different bit depths, the next highest valid bit depth is selected, and ansBIT
(significant bits) chunk is generated that specifies the original precision of the source image. In this case the supplied pixel values will be rescaled to fit the range of the selected bit depth.The PNG file format supports many bit depth / colour model combinations, but not all. The details are somewhat arcane (refer to the PNG specification for full details). Briefly: Bit depths < 8 (1,2,4) are only allowed with greyscale and colour mapped images; colour mapped images cannot have bit depth 16.
For colour mapped images (in other words, when the palette argument is specified) the bitdepth argument must match one of the valid PNG bit depths: 1, 2, 4, or 8. (It is valid to have a PNG image with a palette and an
sBIT
chunk, but the meaning is slightly different; it would be awkward to use the bitdepth argument for this.)The palette option, when specified, causes a colour mapped image to be created: the PNG colour type is set to 3; greyscale must not be set; alpha must not be set; transparent must not be set. The bit depth must be 1,2,4, or 8. When a colour mapped image is created, the pixel values are palette indexes and the bitdepth argument specifies the size of these indexes (not the size of the colour values in the palette).
The palette argument value should be a sequence of 3- or 4-tuples. 3-tuples specify RGB palette entries; 4-tuples specify RGBA palette entries. All the 4-tuples (if present) must come before all the 3-tuples. A
PLTE
chunk is created; if there are 4-tuples then atRNS
chunk is created as well. ThePLTE
chunk will contain all the RGB triples in the same sequence; thetRNS
chunk will contain the alpha channel for all the 4-tuples, in the same sequence. Palette entries are always 8-bit.If specified, the transparent and background parameters must be a tuple with one element for each channel in the image. Either a 3-tuple of integer (RGB) values for a colour image, or a 1-tuple of a single integer for a greyscale image.
If specified, the gamma parameter must be a positive number (generally, a float). A
gAMA
chunk will be created. Note that this will not change the values of the pixels as they appear in the PNG file, they are assumed to have already been converted appropriately for the gamma specified.The compression argument specifies the compression level to be used by the
zlib
module. Values from 1 to 9 (highest) specify compression. 0 means no compression. -1 andNone
both mean that thezlib
module uses the default level of compession (which is generally acceptable).If interlace is true then an interlaced image is created (using PNG’s so far only interace method, Adam7). This does not affect how the pixels should be passed in, rather it changes how they are arranged into the PNG file. On slow connexions interlaced images can be partially decoded by the browser to give a rough view of the image that is successively refined as more image data appears.
Note
Enabling the interlace option requires the entire image to be processed in working memory.
chunk_limit is used to limit the amount of memory used whilst compressing the image. In order to avoid using large amounts of memory, multiple
IDAT
chunks may be created.-
array_scanlines
(pixels)¶ Generates boxed rows (flat pixels) from flat rows (flat pixels) in an array.
-
array_scanlines_interlace
(pixels)¶ Generator for interlaced scanlines from an array. pixels is the full source image in flat row flat pixel format. The generator yields each scanline of the reduced passes in turn, in boxed row flat pixel format.
-
write
(outfile, rows)¶ Write a PNG image to the output file. rows should be an iterable that yields each row in boxed row flat pixel format. The rows should be the rows of the original image, so there should be
self.height
rows ofself.width * self.planes
values. If interlace is specified (when creating the instance), then an interlaced PNG file will be written. Supply the rows in the normal image order; the interlacing is carried out internally.Note
Interlacing requires the entire image to be in working memory.
-
write_array
(outfile, pixels)¶ Write an array in flat row flat pixel format as a PNG file on the output file. See also
write()
method.
-
write_packed
(outfile, rows)¶ Write PNG file to outfile. rows should be in boxed row packed format. Each row should be a sequence of packed bytes.
The rows have a filter byte prefixed and are then compressed into one or more IDAT chunks. They are not processed any further, so if bitdepth is other than 1, 2, 4, 8, 16, the pixel values should have been scaled before passing them to this method.
This method does work for interlaced images but it is best avoided. For interlaced images, the rows should be presented in the order that they appear in the file.
-
write_passes
(outfile, rows)¶ Write a PNG image to the output file.
Most users are expected to find the
write()
orwrite_array()
method more convenient.The rows should be given to this method in the order that they appear in the output file. For straightlaced images, this is the usual top to bottom ordering. For interlaced images the rows should have been interlaced before passing them to this function.
rows should be an iterable that yields each row. The rows should be in boxed row flat pixel format.
-
png.
write_chunks
(out, chunks)¶ Create a PNG file by writing out the chunks.
-
png.
from_array
(a, mode=None, info={})¶ Create a PNG
Image
object from a 2- or 3-dimensional array. One application of this function is easy PIL-style saving:png.from_array(pixels, 'L').save('foo.png')
.Unless they are specified using the info parameter, the PNG’s height and width are taken from the array size. For a 3 dimensional array the first axis is the height; the second axis is the width; and the third axis is the channel number. Thus an RGB image that is 16 pixels high and 8 wide will use an array that is 16x8x3. For 2 dimensional arrays the first axis is the height, but the second axis is
width*channels
, so an RGB image that is 16 pixels high and 8 wide will use a 2-dimensional array that is 16x24 (each row will be 8*3 = 24 sample values).mode is a string that specifies the image colour format in a PIL-style mode. It can be:
'L'
- greyscale (1 channel)
'LA'
- greyscale with alpha (2 channel)
'RGB'
- colour image (3 channel)
'RGBA'
- colour image with alpha (4 channel)
The mode string can also specify the bit depth (overriding how this function normally derives the bit depth, see below). Appending
';16'
to the mode will cause the PNG to be 16 bits per channel; any decimal from 1 to 16 can be used to specify the bit depth.When a 2-dimensional array is used mode determines how many channels the image has, and so allows the width to be derived from the second array dimension.
The array is expected to be a
numpy
array, but it can be any suitable Python sequence. For example, a list of lists can be used:png.from_array([[0, 255, 0], [255, 0, 255]], 'L')
. The exact rules are:len(a)
gives the first dimension, height;len(a[0])
gives the second dimension;len(a[0][0])
gives the third dimension, unless an exception is raised in which case a 2-dimensional array is assumed. It’s slightly more complicated than that because an iterator of rows can be used, and it all still works. Using an iterator allows data to be streamed efficiently.The bit depth of the PNG is normally taken from the array element’s datatype (but if mode specifies a bitdepth then that is used instead). The array element’s datatype is determined in a way which is supposed to work both for
numpy
arrays and for Pythonarray.array
objects. A 1 byte datatype will give a bit depth of 8, a 2 byte datatype will give a bit depth of 16. If the datatype does not have an implicit size, for example it is a plain Python list of lists, as above, then a default of 8 is used.The info parameter is a dictionary that can be used to specify metadata (in the same style as the arguments to the
png.Writer
class). For this function the keys that are useful are:- height
- overrides the height derived from the array dimensions and allows a to be an iterable.
- width
- overrides the width derived from the array dimensions.
- bitdepth
- overrides the bit depth derived from the element datatype (but must match mode if that also specifies a bit depth).
Generally anything specified in the info dictionary will override any implicit choices that this function would otherwise make, but must match any explicit ones. For example, if the info dictionary has a
greyscale
key then this must be true when mode is'L'
or'LA'
and false when mode is'RGB'
or'RGBA'
.