Spaces:
Runtime error
Runtime error
"""Encoder and decoder for PNG files, using PyPNG (png.py). | |
""" | |
import array | |
import itertools | |
from pyglet.image import ImageData, ImageDecodeException | |
from pyglet.image.codecs import ImageDecoder, ImageEncoder | |
import pyglet.extlibs.png as pypng | |
class PNGImageDecoder(ImageDecoder): | |
def get_file_extensions(self): | |
return ['.png'] | |
def decode(self, filename, file): | |
if not file: | |
file = open(filename, 'rb') | |
try: | |
reader = pypng.Reader(file=file) | |
width, height, pixels, metadata = reader.asDirect() | |
except Exception as e: | |
raise ImageDecodeException('PyPNG cannot read %r: %s' % (filename or file, e)) | |
if metadata['greyscale']: | |
if metadata['alpha']: | |
fmt = 'LA' | |
else: | |
fmt = 'L' | |
else: | |
if metadata['alpha']: | |
fmt = 'RGBA' | |
else: | |
fmt = 'RGB' | |
pitch = len(fmt) * width | |
pixels = array.array('BH'[metadata['bitdepth'] > 8], itertools.chain(*pixels)) | |
return ImageData(width, height, fmt, pixels.tobytes(), -pitch) | |
class PNGImageEncoder(ImageEncoder): | |
def get_file_extensions(self): | |
return ['.png'] | |
def encode(self, image, filename, file): | |
image = image.get_image_data() | |
has_alpha = 'A' in image.format | |
greyscale = len(image.format) < 3 | |
if has_alpha: | |
if greyscale: | |
image.format = 'LA' | |
else: | |
image.format = 'RGBA' | |
else: | |
if greyscale: | |
image.format = 'L' | |
else: | |
image.format = 'RGB' | |
image.pitch = -(image.width * len(image.format)) | |
writer = pypng.Writer(image.width, image.height, greyscale=greyscale, alpha=has_alpha) | |
data = array.array('B') | |
data.frombytes(image.get_data(image.format, image.pitch)) | |
writer.write_array(file, data) | |
def get_decoders(): | |
return [PNGImageDecoder()] | |
def get_encoders(): | |
return [PNGImageEncoder()] | |