-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpng.py
37 lines (31 loc) · 1.2 KB
/
png.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import zlib, struct
import numpy as np
def Build(image_data, palette=None):
def png_pack(head, data):
chunk = head + data
return (struct.pack("!I", len(data)) +
chunk +
struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk)))
if palette is None:
color_type = 0
transparent = b'\x00\x00'
pal = ''
else:
color_type = 3
pal = png_pack(b'PLTE', b''.join([struct.pack('!3B', 0xFF & b>>16, 0xFF & b>>8, 0xFF & b) for b in palette]))
if np.any(palette>=16777216):
transparent = b''.join([struct.pack('!B', 255-(0xFF & b>>24)) for b in palette])
else:
transparent = b'\x00'
height, width = image_data.shape
# Prepend each scan line with 0 for the filter type
scan = np.zeros((height, width+1), np.uint8)
scan[:,1:] = image_data;
raw = scan.tobytes()
return b''.join([
b'\x89PNG\r\n\x1a\n',
png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, color_type, 0, 0, 0)),
pal,
png_pack(b'tRNS', transparent),
png_pack(b'IDAT', zlib.compress(raw)),
png_pack(b'IEND', b'')])