Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # png_encoder.py
- dir=r"C:/pydemo/test/"
- DEPTH = 24
- # Color depth [bytes/pixel]
- # 1 Black and White
- # 8 Grayscale
- # 24 RGB
- # 32 RGBA
- # Script
- import struct
- import zlib
- import binascii
- import os
- def make_png(OUTPUT_FILE, DATA, IMAGE_W, IMAGE_H):
- class pngEncorder:
- compressor = zlib.compressobj(9) # max compression
- out = lambda: None
- length = 0
- crc32 = 0x35AF061E # crc32("IDAT")
- def __init__(self, out):
- self.out = out
- def writeRaw(self, b):
- self.out(b)
- self.length += len(b)
- self.crc32 = zlib.crc32(b, self.crc32)
- def write(self, b):
- self.writeRaw(self.compressor.compress(b))
- # improved write() for many zero bytes
- def writez(self, num):
- for i in range(num >> 14):
- self.out(self.compressor.compress(zero16KiB))
- self.crc32 = zlib.crc32(zero16KiB, self.crc32)
- num &= 0x3FFF
- self.out(self.compressor.compress(b"\0" * num))
- self.crc32 = zlib.crc32(b"\0" * num, self.crc32)
- self.length += num
- def finalize(self):
- self.writePixels()
- self.writeRaw(self.compressor.flush())
- def B(x):
- return struct.pack(">B", x & 0xFF)
- def I4(x):
- return struct.pack(">I", x & 0xFFFFFFFF)
- zero16KiB = b"\0" * 16383
- width = IMAGE_W
- height = IMAGE_H
- bitdepth = 8 # [bit/sample]
- if DEPTH == 1:
- bitdepth = 1
- colortype = 0
- elif DEPTH == 8:
- colortype = 0
- elif DEPTH == 24:
- colortype = 2
- elif DEPTH == 32:
- colortype = 6
- else:
- raise NotImplementedError("Unsupported color depth {0}".format(DEPTH))
- compresstype = 0 # zlib (only supported method)
- filtermethod = 0 # adaptive (only supported method)
- interlaced = 0 # no
- maxEntropyBits = DEPTH * IMAGE_W * IMAGE_H
- if DEPTH == 1:
- bytesPerRow = (DEPTH * IMAGE_W + 7) >> 3
- else:
- bytesPerPixel = DEPTH >> 3
- pixelPadding = bytesPerPixel
- bytesPerRow = bytesPerPixel * IMAGE_W
- class rgbEncorder(pngEncorder):
- def writePixels(self):
- # This method uses globals, which is probably bad...
- d = DATA[:]
- for y in range(IMAGE_H):
- self.write(b"\x00") #
- for x in range(IMAGE_W):
- magic = d.pop(0)
- magic = [chr(z) for z in magic]
- self.write(''.join(magic))
- with open(OUTPUT_FILE, "wb") as f:
- # Signature
- f.write(b"\x89PNG\r\n\x1A\n")
- # IHDR
- IHDR = b"IHDR" \
- + I4(width) \
- + I4(height) \
- + B(bitdepth) \
- + B(colortype) \
- + B(compresstype) \
- + B(filtermethod) \
- + B(interlaced)
- f.write(I4(len(IHDR) - 4)) # 13
- f.write(IHDR)
- f.write(I4(zlib.crc32(IHDR)))
- # IDAT
- IDAT_len_offset = f.tell() # 33
- f.write(b"\0\0\0\0IDAT")
- rgb = rgbEncorder(f.write)
- rgb.finalize()
- f.write(I4(rgb.crc32))
- f.seek(IDAT_len_offset)
- f.write(I4(rgb.length))
- f.seek(0, 2) #
- f.write(b"\0\0\0\0IEND\xae\x42\x60\x82")
- 0
- make_png(dir+str(99)+"_demo.png",[(0,255,0)]*(100*100),100,100)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement