saving a numpy array as a io.BytesIO with jpg format - python

I am using xlsxwriter to insert image into excel in python code.
Now, I had image data(numpy array) after opencv process. I would like insert this image data to excel. But xlswriter only support io.BytesIO stream.
question: I don't know how to convert numpy array to io.BytesIO with jpg format.
I have trying numpy.tostring but without jpg format.
the code working well in below:
_f = open('test.jpg') # I would like to insert test.jpg
worksheet.insert_image('E2', 'abc.jpg', {'image_data': _f.read()})
Anybody can help me ? thank you so much.

Convert the numpy arrays to PIL Image structure, then use BytesIO to store the encoded image.
img_crop_pil = Image.fromarray(numpy_image)
byte_io = BytesIO()
img_crop_pil.save(byte_io, format="JPG")
jpg_buffer = byte_io.getvalue()
byte_io.close()

Use the cv2.imencode function to convert a numpy array to jpg format.

Related

Reading a binary image directly to OpenCV Mat / numpy mat

Through some http requests I have been able to receive an image in binary form as
b'\xff\xd8\xff\xe0\x00\...
and with:
with open('image.jpg', 'wb') as out_file:
out_file.write(binary_content)
where binary_content is a string containing the data received through request I saved an image into a file.
Afterwards I can read this image with OpenCV methods. But I wanted to do a direct pass from binary string to OpenCV Mat without any in-betweens. cv2.decode method didn't work.
io.BytesIO and PIL worked well. Closing this q.
If you want to stay in the SciPy ecosystem, then the imageio library (previously part of SciPy) works well.
from imageio import imread
image_array = imread("image_path.jpg")
The code above gives you an uint8 array, if you want a float array, you can cast it easily
from imageio import imread
image_array = imread("image_path.jpg").astype(float)

How do I encode a numpy array to a base64-encoded PNG without writing to disk?

I want to convert an image, represented as a numpy array, into a base64-encoded PNG string, without writing it as a file to disk first.
The goal is to send this over HTTP, and then display the image in a browser using Javascript. Basically trying to send a numpy image array to a browser without using disk.
I'm very comfortable on the python side, and quite unfamiliar on the JS side.
I don't want to use disk, and I don't want to use tensorflow (which has a related helper API).
I have tried researching, but everything that converts a numpy array to a PNG seems to want to save it to disk. I don't know how to avoid the disk I/O.
Many functions that create files will accept an instance of io.StringIO or io.BytesIO instead of a filename or file object.
Here's an example (in an ipython session) where I use numpngw.write_png (from numpngw, a package I wrote for creating PNG and animated PNG files from numpy arrays) to create a base64-encoded PNG file in a Python bytes object.
First, the imports:
In [39]: import numpy as np
In [40]: from numpngw import write_png
In [41]: import io
In [42]: import base64
Create an image to work with:
In [43]: img = np.random.randint(0, 256, size=(16, 16, 3)).astype(np.uint8)
Create a BytesIO object, and write the PNG "file" to it.
In [44]: f = io.BytesIO()
In [45]: write_png(f, img)
f.getvalue() gets the bytes in the PNG "file". Take a peek at the first 12 bytes:
In [46]: f.getvalue()[:12]
Out[46]: b'\x89PNG\r\n\x1a\n\x00\x00\x00\r'
Finally, use one of the many encodings available in the base64 library to encode the PNG data:
In [47]: b64 = base64.b64encode(f.getvalue())
In [48]: b64
Out[48]: b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAInRFWHRDcmVhdGlvbiBUaW1lADIwMTktMTAtMThUMDI6NDY6MTRayfRM7AAAAFF0RVh0U29mdHdhcmUAbnVtcG5ndyAodmVyc2lvbiAwLjAuOS5kZXYwKSwgaHR0cHM6Ly9naXRodWIuY29tL1dhcnJlbldlY2tlc3Nlci9udW1wbmd3aGhwYwAAAxtJREFUeJwBEAPv/AChDcGkLZrMNsaw4b5CRQk90PGcAA05N+8BH3rlSGZVLOn/vleX3mclnyfC1TXEOJYAfLtv7F3kSclGhnJDU93XTTWA2RcAutMYkETtG2kUZMWvbSDAxm0uSm8y0Do6gNQpANrN6Xt3cIoybwKclwb9jEQoIrdE6acAd4IoaaSEuH2mUIZ0tQ5plhBU61nCj7jBqQBQFH2x7wd5HR3IA5jo/jOrlalRhR2xgYRboyOl+MhIxExUhNjqEpz66SGJQNbUrWoAYQIWoEgFXiewRwACPUd35eo0DxDWYcrONkmj1fBGe03/JirvaJLQ79F7uAG2vrCXACLBrKntrzxPLoFa7Wgzl1nNEdo7Fenn7Jd+d2TAAMFELJTkhXAhUpQe3NyIjY9y+QD0Lmn11S/UYf4BcTqE3lMbbQ2iQpS1kcKOtbC2zjx7KovsK1M+JRIClOUzATlVnp8ANJS/zfP2ZTzR4dKjV2XfF3bxFs9Kk9qb+ilBHlBUSr2VA6CHxxVtcuvlkeiDvSA6AFQjA+Hd5vsgjgAcEUPkJx2SgqazSjXcSFFyQHqhgif47p3WOVM2lv0rWc4kSRwE5QCXsYTzOWusqZPbHxZSIWDvPjZcESUQ6FKZ4Pa0XFfdD2rLxp/4PF6w33k75h6uHpMAJWGC0yVRXBRW726WM9BAoX7+KjhLaJ6FhJ5aeRYL092uW8DxFwgPTq/evQg6PgOZAOWyz+saW+gMZukrMeZyQLQcQ5QMzX0sFXBtT7rAs9sEKUIx/HLH6wuTCd+zkzbvbAD6cNATGxklmLG15gwnLIX5bSCFD3wTAhDZwaXTdvUDt6LGc7oma5QfuVKUPGXtm7MAIghIuKbNd6S1wsqG6Ga/cB+wMJYklc5AG4dGzFnK+RbpACrQtchNn9v6o2zXJxjaAIaIY6VW1Db6VNeP/tXKHrusaqy1lssoVdSNGiDMo17vmM4EsTkqSkNMFAMct78+WQCb6h4CwetL6rzaQvUx03qW4GBgPbIEMe2MIS9l7D53VKdtUjhpl28zOqI5bW3YFN4cXne4IEUrgwAAAABJRU5ErkJggg=='

Convert .h5 file to .jpg with Python

I currently have a .h5 file containing grayscale imagery. I need to convert it to a .jpg.
Does anybody have any experience with this?
Note: I could possible convert the h5 file to a numpy array and then use an external library like pypng to convert that to a png. But I am wondering if there is a more efficient way to convert to an image, and preferrably a .jpg.
Key ingredients:
h5py to read the h5 file.
Determine the format of your image and use PIL.
Let us suppose it's RGB format (https://support.hdfgroup.org/products/java/hdfview/UsersGuide/ug06imageview.html)
Suppose your image is located at Photos/Image 1 then you can do.
import h5py
import numpy as np
from PIL import Image
hdf = h5py.File("Sample.h5",'r')
array = hdf["Photos/Image 1"][:]
img = Image.fromarray(array.astype('uint8'), 'RGB')
img.save("yourimage.thumbnail", "JPEG")
img.show()

How do I convert the x-genericbytedata-octet-stream to some format which is readable/manageable

I am calling a imageServer and getting an x-genericbytedata-octet-stream in response. So i was wondering if i can convert it into some format which is manageable like ndarray.
This is what i am getting in response
ÿ Ç÷®£®¥Xøan Ð5£ï~KTþ$¹M«_ ü³þœÿ ˆk¡çÆHyAÏbG§ø
A«÷g~ŒieÞÁn¦=Ÿüú
i.¿†ö#µ2lí~¤ŸðjLóÉ&,X.ó¿:ÿ
õ¿*ìüTv蚃zXÌñÓ\•Ÿû[X’ĩ쀀0wOóÀ®ŸÆm·Ãú‘ÿ
§?¡¬ª|f‘Øñx^àÁW\móVà„³Éä˜Óý’3úÔ­pë¬P2€2pGõö?Z’êàÛDÊ=­jȶ¤3ÝÝÜb”vägõ¯wÑß
z‹8óøŠðy®¤U8³ÄIüÇå^ù§åt]0cìq?೫иQñÔkVØ·fàú±ÿ
I want to convert it into an ndarray so that I could use it in opencv.
Thanks
You can use Pillow and StringIO to convert it to a jpeg image.
from PIL import Image
import StringIO
img = Image.open(StringIO.StringIO(image_data))
print (img.size)

Store a base64 image in python memory, then retrieve for use in wxpython/PIL

1) I have an image that I converted to a string. It looks like this:
bytesimage = b'iVBORw0KGgoAAAANSUhEUgA.... etc etc
2) I can convert it to an 'bytesimage.png' using:
def StringToImage(self, stringname, imageoutput):
imgdata = base64.b64decode(stringname)
imagename = imageoutput
with open(imagename, 'wb') as f:
f.write(imgdata)
3) But then I want to save that image or string to memory to use in wxpython interface without needing to save the file. I have seen several related questions where the solution is using io.BytesIO, but I just cant connect the steps and both wxpython or PIL don't seem to read the bytes properly.
So to clarify:
I have a image stored in a string DONE
I can convert that to an image (if needed) but dont want to save it DONE
I need that string OR image (whichever is best) saved to memory NEEDS SOLVING
Then I want to be able to use that image in wxpython (I can open in PIL first if required)
Any help would be fantastic!
StringIO seems to be the way to go. It allows you to pass the decoded string directly to PIL.
import base64
from PIL import Image
import StringIO
# Banana emoji (JPG) as a b64 string.
b64_img_str = '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'
# Decode back to the original bytes
new_img_str = base64.b64decode(b64_img_str)
# Use StringIO to provide an in-memory buffer that we can use
# to pass the image string to PIL.
sio = StringIO.StringIO(new_img_str)
img = Image.open(sio)
# Display the image
img.show()

Categories