I want to write a single channel png image from a numpy array in python? In Matlab that would be
A = randi(100,100,255)
imwrite(uint8(A),'myFilename.png','png');
I saw exampels using from PIL import Image
and Image.fromarray()
but they are for jpeg and 3-channel pngs only it appears...
I already found the solution using opencv, I will post it here. Hopefully it will shorten someone else's searching...
PIL's Image.fromarray()
automatically determines the mode to use from the datatype of the passed numpy array, for example for an 8-bit greyscale image you can use:
from PIL import Image
import numpy as np
data = np.random.randint(256, size=(100, 100), dtype=np.uint8)
img = Image.fromarray(data) # uses mode='L'
This however only works if your array uses a compatible datatype, if you simply use data = np.random.randint(256, size=(100, 100))
that can result in a int64 array (typestr <i8
), which PIL can't handle.
You can also specify a different mode, e.g. to interpret a 32bit array as an RGB image:
data = np.random.randint(2**32, size=(100, 100), dtype=np.uint32)
img = Image.fromarray(data, mode='RGB')
Internally Image.fromarray()
simply tries to guess the correct mode and size and then invokes Image.frombuffer()
.
The image can then be saved as any format PIL
can handle e.g: img.save('filename.png')
Here is a solution using opencv / cv2
import cv2
myImg = np.random.randint(255, size=(200, 400)) # create a random image
cv2.imwrite('myImage.png',myImg)
You might want not to utilise OpenCV for simple image manipulation. As suggested, use PIL:
im = Image.fromarray(arr)
im.save("output.png", "PNG")
Have you tried this? What has failed here that led you to concluding that this is JPEG-only?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With