# Python : Media : pypng
\[ [src](https://gitlab.com/drj11/pypng/) | [docs](https://drj11.gitlab.io/pypng/) ]
## Concepts & Values
#### Color Modes
```
L Greyscale
LA Greyscale with alpha
RGB RGB
RGBA RGB with alpha
or Palette-based
```
> [!NOTE] Appending Bitdepth
> When passing color mode values to pypng, you can append a bitdepth like this: "L;8" or "RGB;16"
#### Pixel Data
```python
# L — three pixels by two pixels
[
[ L, L, L ],
[ L, L, L ],
]
# LA — three pixels by two pixels
[
[ L,A, L,A, L,A ],
[ L,A, L,A, L,A ],
]
# RGB — three pixels by two pixels
[
[ R,G,B, R,G,B, R,G,B ],
[ R,G,B, R,G,B, R,G,B ],
]
# RGBA — three pixels by two pixels
[
[ R,G,B,A, R,G,B,A, R,G,B,A ],
[ R,G,B,A, R,G,B,A, R,G,B,A ],
]
```
#### Palette Data
```python
# Palette for image with bitdepth = 1 has only two possible colors.
# If we want transparency, we can use RGBA 4‑tuples for each palette entry.
[ [ R,G,B ], [ R,G,B ] ]
```
## API
#### Imports
```python
from png import Image, Reader, Writer, from_array, iwrite_chunks
```
#### Classes
```python
Image
__init__( rows, info )
rows -> itertools._tee
info -> { greyscale, alpha, height, width, bitdepth }
save( "filename" ) # can only call save/write once;
write( file ) # it consumes the source stream
stream() # stream the rows into a list so .rows can be access multiple times
Reader
__init__( _guess = None, filename = None, file = None, bytes = None ) # expects one
preamble() # extract metadata by reading initial part of file up to IDAT chunk
read() -> width, height, pixels, metadata
asDirect() -> width, height, pixels, metadata
asRGB() -> width, height, pixels, metadata
asRGBA() -> width, height, pixels, metadata
# pixels -> [ bytearray ]
# metadata -> { greyscale, alpha, planes, bitdepth, interlace, size }
chunk() -> ( type, data ) # return next chunk from input file
chunks() -> iter:( type, data )
palette( alpha = "natural" ) -> ???
# FormatError: Required PLTE chunk is missing in colour type 3 image.
# Properties
alpha # False
bitdepth # 8
color_planes # 3
color_type # 2
colormap # False
compression # 0
file.name # "a.png"
filter # 0
greyscale # False
height # 512
interlace # 0
planes # 3
plte # None
psize # 3
row_bytes # 1536
sbit # None
signature # b'\x89PNG\r\n\x1a\n'
transparent # None
trns # None
width # 512
Writer
__init__(
width = None,
height = None,
size = None,
greyscale = png.Default,
alpha = False,
bitdepth = 8, # 1 .. 16
palette = None, # (creates PLTE)
transparent = None, # transparent color (creates tRNS)
background = None, # default bg color (creates bKGD)
gamma = None,
compression = None, # 0..9
planes = None, # values per pixel
maxval = None,
chunk_limit = 1048576,
physical = (),
x_pixels_per_unit = None,
y_pixels_per_unit = None,
unit_is_meter = False
)
write( file, rows ) # rows := iterable of iterable of pixels
```
#### Functions
```python
from_array( a, mode = None, info = {} ) -> png.Image
# ex: from_array( [ [ 255, 0, 0, 255 ], [ 0, 255, 255, 0 ] ], "L" )
write_chunks( out, chunks )
```
## Chunk Types
- IHDR — Generated automatically by PyPNG.
- PLTE — Correctly handled when a PNG image is read. For writing, use the `palette` argument to the `png.Writer()`. This can work with PNG color type 3 (palette required), and other color types (palette optional).
- IDAT — Generated automatically from the pixel data presented to PyPNG. Multiple `IDAT` chunks (of bounded size) can be generated by using `chunk_limit` argument to the `png.Writer()`.
- IEND — Generated automatically.
- tRNS — When writing, generated for most color types when the `transparent` argument is supplied to `png.Writer()` to specify a transparent color. For color type 3, color mapped images, a `tRNS` chunk will be generated automatically from the `palette` argument when a palette with alpha (opacity) values is supplied. When reading, will be processed into the alpha channel (if the appropriate method is used).
- cHRM — Ignored when reading. Not generated.
- gAMA — When reading a PNG image the `gAMA` chunk is converted to a floating point gamma value; this value is returned in `info[ "gamma" ]`. When writing, the `gamma` argument to `png.Writer()` class will generate a `gAMA` chunk. Note that there is no code to adjust the pixel values for gamma. Your code has to do that, if you want it.
- iCCP — International Color Consortium Profile. Ignored when reading. Not generated.
- sBIT — When reading a PNG image the `sBIT` chunk will make PyPNG rescale the pixel values so that they all have the width implied by the `sBIT` chunk. It is possible for a PNG image to have an `sBIT` chunk that specifies 3 different values for the significant bits in each of the 3 colour channels. In this case PyPNG only uses the largest value. When writing a PNG image, an `sBIT` chunk will be generated if needed according to the `bitdepth` argument specified. Values other than 1, 2, 4, 8, or 16 will generate an `sBIT` chunk, as will values less than 8 for images with more than one plane.
- sRGB — Ignored when reading. Not generated.
- tEXt — Ignored when reading. Not generated.
- zTXt — Ignored when reading. Not generated.
- iTXt — Ignored when reading. Not generated.
- bKGD — When a PNG image is read, a `bKGD` chunk will add the `background` key to the `info` dictionary. When writing a PNG image, a `bKGD` chunk will be generated when the `background` argument is used.
- hIST — Ignored when reading. Not generated.
- pHYs — When a PNG image is read, a `pHYs` chunk will add the `physical` key to the `info` dictionary. When writing a PNG image, a `pHYs` chunk will be generated if `x_pixels_per_unit` and `y_pixels_per_unit` is not `None`. The default is to not write this chunk.
- sPLT — Ignored when reading. Not generated.
- tIME — Ignored when reading. Not generated.