Ich habe eine Matrix in der Art eines Numpy-Arrays. Wie würde ich sie als Bild auf die Festplatte schreiben? Jedes Format funktioniert (png, jpeg, bmp...). Eine wichtige Randbedingung ist, dass PIL nicht vorhanden ist.
Antworten
Zu viele Anzeigen?Nachtrag zur Antwort von @ideasman42:
def saveAsPNG(array, filename):
import struct
if any([len(row) != len(array[0]) for row in array]):
raise ValueError, "Array should have elements of equal size"
#First row becomes top row of image.
flat = []; map(flat.extend, reversed(array))
#Big-endian, unsigned 32-byte integer.
buf = b''.join([struct.pack('>I', ((0xffFFff & i32)<<8)|(i32>>24) )
for i32 in flat]) #Rotate from ARGB to RGBA.
data = write_png(buf, len(array[0]), len(array))
f = open(filename, 'wb')
f.write(data)
f.close()
Das können Sie tun:
saveAsPNG([[0xffFF0000, 0xffFFFF00],
[0xff00aa77, 0xff333333]], 'test_grid.png')
Herstellung von test_grid.png
:
(Transparenz funktioniert auch, indem das hohe Byte von 0xff
.)
Für diejenigen, die ein direktes, voll funktionsfähiges Beispiel suchen:
from PIL import Image
import numpy
w,h = 200,100
img = numpy.zeros((h,w,3),dtype=numpy.uint8) # has to be unsigned bytes
img[:] = (0,0,255) # fill blue
x,y = 40,20
img[y:y+30, x:x+50] = (255,0,0) # 50x30 red box
Image.fromarray(img).convert("RGB").save("art.png") # don't need to convert
Wenn Sie außerdem qualitativ hochwertige Jpeg-Dateien wünschen
.save(file, subsampling=0, quality=100)
Matplotlib svn hat eine neue Funktion, um Bilder als nur ein Bild zu speichern -- keine Achsen usw. Es ist eine sehr einfache Funktion, die man auch zurückportieren kann, wenn man svn nicht installieren möchte (direkt aus image.py in matplotlib svn kopiert, den docstring der Kürze halber entfernt):
def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None):
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False)
canvas = FigureCanvas(fig)
fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin)
fig.savefig(fname, dpi=1, format=format)
Die Welt braucht wahrscheinlich nicht noch ein weiteres Paket, um ein Numpy-Array in eine PNG-Datei zu schreiben, aber für diejenigen, die nicht genug bekommen können, habe ich kürzlich ein numpngw
auf Github:
https://github.com/WarrenWeckesser/numpngw
und auf pypi: https://pypi.python.org/pypi/numpngw/
Die einzige externe Abhängigkeit ist numpy.
Hier ist das erste Beispiel aus dem examples
Verzeichnis des Repositorys. Die wichtigste Zeile ist einfach
write_png('example1.png', img)
donde img
ist ein Numpy-Array. Der gesamte Code vor dieser Zeile besteht aus Importanweisungen und Code zum Erstellen von img
.
import numpy as np
from numpngw import write_png
# Example 1
#
# Create an 8-bit RGB image.
img = np.zeros((80, 128, 3), dtype=np.uint8)
grad = np.linspace(0, 255, img.shape[1])
img[:16, :, :] = 127
img[16:32, :, 0] = grad
img[32:48, :, 1] = grad[::-1]
img[48:64, :, 2] = grad
img[64:, :, :] = 127
write_png('example1.png', img)
Hier ist die PNG-Datei, die erstellt wird:
Außerdem habe ich numpngw.write_apng
zur Erstellung der Animationen in Voronoi-Diagramm in Manhattan-Metrik .
Imageio ist eine Python-Bibliothek, die eine einfache Schnittstelle zum Lesen und Schreiben einer breiten Palette von Bilddaten bietet, einschließlich animierter Bilder, Videos, volumetrischer Daten und wissenschaftlicher Formate. Sie ist plattformübergreifend, läuft auf Python 2.7 und 3.4+ und ist einfach zu installieren.
Dies ist ein Beispiel für ein Graustufenbild:
import numpy as np
import imageio
# data is numpy array with grayscale value for each pixel.
data = np.array([70,80,82,72,58,58,60,63,54,58,60,48,89,115,121,119])
# 16 pixels can be converted into square of 4x4 or 2x8 or 8x2
data = data.reshape((4, 4)).astype('uint8')
# save image
imageio.imwrite('pic.jpg', data)