I have an application where I would like to be able to generate PNG images from data in Python. I've done some searching and found "PIL" which looked pretty outdated. Is there some other library that would be better for this?
Is there some other library that would be better for this?
The png package would be a reasonable common choice.
Here's the project description:
PyPNG allows PNG image files to be read and written using pure Python.
Simple PNG files can be generated quite easily from pure Python code - all you need is the standard zlib module and some bytes-encoding to write the chunks. Here is a complete example that the casual reader may use as a starter for their own png generator:
#! /usr/bin/python
""" Converts a list of list into gray-scale PNG image. """
__copyright__ = "Copyright (C) 2014 Guido Draheim"
__licence__ = "Public Domain"
import zlib
import struct
def makeGrayPNG(data, height = None, width = None):
def I1(value):
return struct.pack("!B", value & (2**8-1))
def I4(value):
return struct.pack("!I", value & (2**32-1))
# compute width&height from data if not explicit
if height is None:
height = len(data) # rows
if width is None:
width = 0
for row in data:
if width < len(row):
width = len(row)
# generate these chunks depending on image type
makeIHDR = True
makeIDAT = True
makeIEND = True
png = b"\x89" + "PNG\r\n\x1A\n".encode('ascii')
if makeIHDR:
colortype = 0 # true gray image (no palette)
bitdepth = 8 # with one byte per pixel (0..255)
compression = 0 # zlib (no choice here)
filtertype = 0 # adaptive (each scanline seperately)
interlaced = 0 # no
IHDR = I4(width) + I4(height) + I1(bitdepth)
IHDR += I1(colortype) + I1(compression)
IHDR += I1(filtertype) + I1(interlaced)
block = "IHDR".encode('ascii') + IHDR
png += I4(len(IHDR)) + block + I4(zlib.crc32(block))
if makeIDAT:
raw = b""
for y in xrange(height):
raw += b"\0" # no filter for this scanline
for x in xrange(width):
c = b"\0" # default black pixel
if y < len(data) and x < len(data[y]):
c = I1(data[y][x])
raw += c
compressor = zlib.compressobj()
compressed = compressor.compress(raw)
compressed += compressor.flush() #!!
block = "IDAT".encode('ascii') + compressed
png += I4(len(compressed)) + block + I4(zlib.crc32(block))
if makeIEND:
block = "IEND".encode('ascii')
png += I4(0) + block + I4(zlib.crc32(block))
return png
def _example():
with open("cross3x3.png","wb") as f:
f.write(makeGrayPNG([[0,255,0],[255,255,255],[0,255,0]]))
Here's a Python3 example:
import png
width = 255
height = 255
img = []
for y in range(height):
row = ()
for x in range(width):
row = row + (x, max(0, 255 - x - y), y)
img.append(row)
with open('gradient.png', 'wb') as f:
w = png.Writer(width, height, greyscale=False)
w.write(f, img)
Is there some other library that would be better for this?
The png package would be a reasonable common choice.
Here's the project description:
PyPNG allows PNG image files to be read and written using pure Python.
After doing some searching, I found this site: https://www.daniweb.com/programming/software-development/code/454765/save-a-pygame-drawing. It just uses good old pygame.
Line 37: (pg.image.save(win, fname)
) saves whatever is drawn on the pygame surface as a file.
EDIT
Here is the actual code:
"""pg_draw_circle_save101.py
draw a blue solid circle on a white background
save the drawing to an image file
for result see http://prntscr.com/156wxi
tested with Python 2.7 and PyGame 1.9.2 by vegaseat 16may2013
"""
import pygame as pg
# pygame uses (r, g, b) color tuples
white = (255, 255, 255)
blue = (0, 0, 255)
width = 300
height = 300
# create the display window
win = pg.display.set_mode((width, height))
# optional title bar caption
pg.display.set_caption("Pygame draw circle and save")
# default background is black, so make it white
win.fill(white)
# draw a blue circle
# center coordinates (x, y)
center = (width//2, height//2)
radius = min(center)
# width of 0 (default) fills the circle
# otherwise it is thickness of outline
width = 0
# draw.circle(Surface, color, pos, radius, width)
pg.draw.circle(win, blue, center, radius, width)
# now save the drawing
# can save as .bmp .tga .png or .jpg
fname = "circle_blue.png"
pg.image.save(win, fname)
print("file {} has been saved".format(fname))
# update the display window to show the drawing
pg.display.flip()
# (press escape key or click window title bar x to exit)
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
# most reliable exit on x click
pg.quit()
raise SystemExit
elif event.type == pg.KEYDOWN:
# optional exit with escape key
if event.key == pg.K_ESCAPE:
pg.quit()
raise SystemExit
I'm aware that this question was asked over 9 years ago, but in the age of Python 3.8, you can just open the file in "Writing Binary" mode:
f = open("filename.png", 'wb')
# data being whatever data you wanted to write
f.write(data)
© 2022 - 2024 — McMap. All rights reserved.