PNG encoder in pure Python.
Constructor:
Create a PNG encoder object.
Arguments:
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 source pixel value must be an integer between 0 and 2**bitdepth-1. 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. When bitdepth is not one of these values, the next highest valid bit depth is selected, and an sBIT (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 details of which bit depth / colour model combinations the PNG file format supports directly, are somewhat arcane (refer to the PNG specification for full details). Briefly: “small” bit depths (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 press the bitdepth argument into service 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. If both 4-tuples and 3-tuples appear in the sequence then all the 4-tuples must come before all the 3-tuples. A PLTE chunk is created; if there are 4-tuples then a tRNS chunk is created as well. The PLTE chunk will contain all the RGB triples in the same sequence; the tRNS 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 three integer values for red, green, blue, or a simple integer (or singleton tuple) 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 specify compression, with 9 being “more compressed” (usually smaller and slower, but it doesn’t always work out that way). 0 means no compression. -1 and None both mean that the default level of compession will be picked by the zlib module (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 presented to the encoder, 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.
Methods:
array_scanlines(pixels) Generates boxed rows (flat pixels) from flat rows (flat pixels) array_scanlines_interlace(pixels) Generator for interlaced scanlines from an array. convert_pnm(infile, outfile) Convert a PNM file containing raw pixel data into a PNG file convert_ppm_and_pgm(ppmfile, pgmfile, outfile) Convert a PPM and PGM file containing raw pixel data into a file_scanlines(infile) Generates boxed rows in flat pixel format, from the input file infile. make_palette() Create the byte sequences for a PLTE and if necessary a write(outfile, rows) Write a PNG image to the output file. rows should be write_array(outfile, pixels) Write an array in flat row flat pixel format as a PNG file on write_packed(outfile, rows) Write PNG file to outfile. The pixel data comes from rows write_passes(outfile, rows[, packed]) Write a PNG image to the output file.
Generates boxed rows (flat pixels) from flat rows (flat pixels) in an array.
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.
Convert a PNM file containing raw pixel data into a PNG file with the parameters set in the writer object. Works for (binary) PGM, PPM, and PAM formats.
Convert a PPM and PGM file containing raw pixel data into a PNG outfile with the parameters set in the writer object.
Generates boxed rows in flat pixel format, from the input file infile. It assumes that the input file is in a “Netpbm-like” binary format, and is positioned at the beginning of the first pixel. The number of pixels to read is taken from the image dimensions (width, height, planes) and the number of bytes per value is implied by the image bitdepth.
Create the byte sequences for a PLTE and if necessary a tRNS chunk. Returned as a pair (p, t). t will be None if no tRNS chunk is necessary.
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 of self.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 will require the entire image to be in working memory.
Write an array in flat row flat pixel format as a PNG file on the output file. See also write() method.
Write PNG file to outfile. The pixel data comes from rows which should be in boxed row packed format. Each row should be a sequence of packed bytes.
Technically, 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.
This method should not be used when the source image bit depth is not one naturally supported by PNG; the bit depth should be 1, 2, 4, 8, or 16.
Write a PNG image to the output file.
Most users are expected to find the write() or write_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, but for interlaced images the rows should have already been interlaced before passing them to this function.
rows should be an iterable that yields each row. When packed is False the rows should be in boxed row flat pixel format; when packed is True each row should be a packed sequence of bytes.