Create a file object from raw binary information in Python - python

Question
What is a clean way to create a file object from raw binary information in Python?
More Info
The reason I need to do this is because I have the raw binary information comprising a jpeg image stored in ram. I need to put it inside some kind of file object so that I can resize the image using Python's Pillow library.
According to the pillow documentation, the file object needs to implement the read(), seek(), and tell() methods.
The file object must implement read(), seek(), and tell() methods, and be opened in binary mode.

I was able to find a mention of how to handle this situation under the documentation for PIL.Image.frombytes:
...If you have an entire image in a string, wrap it in a BytesIO object,
and use open() to load it.
This is what I ended up with that worked using BytesIO:
import io
import PIL
from PIL.Image import Image
file_body = <binary image data>
t_file = io.BytesIO(file_body)
img = PIL.Image.open(t_file)
Note: The comments mention tempfile.SpooledTemporaryFile. This seems like it should have worked, but it did not for some reason.

Related

How to use image binary data directly in kivy for widgets like icon and FloatButtons

I have few icon pics who's binary form is stored in database . now I have few approaches:
To take the binary data from database and covert it into a png or jpeg file and store it on the user's device
or
To directly use the binary data without storing it on user's device
I prefer the second one . but the problem is the kivy widgets such as MDIcon or FloatButtton needs a string of address and not binary data so is their a way to resolve this .
And please let me know if their is a better way of solving this issue.
You can convert an image without saving it on the drive like this.
from io import BytesIO
def convertToJpeg(img):
with BytesIO() as f:
img.save(f, format='JPEG')
return f.getvalue()

Python function requires path but I have an image stored in memory

I have a python function (using the Pythonista app) to show an image in the console. I have the image saved in a BytesIO object but the function requires a file path.
Is there any way to give it a path to the bytesIO or somehow give it the image without needing to save it as a file?
The specific function is console.show_image(image_path)
The general answer is that if the function you call expects a filesystem path and cannot handle a file-like object instead then your only solution is to write your data to a file (and ask the function's author to add support for file-like object, or if it's OSS implement it by yourself and send a merge request).

convert python StringIO to BufferedReader

I am using two different libraries. One gives out a stream as StringIO. Another library expects a File like object and invokes read method on it. I don't want to persist the stream to a tempfile, to avoid disk IO operations.
Is there a way to create a BufferedReader from StringIO object ?
Is there a different approach to handle this problem ?
Environment details : Python 2.7

Load uploaded image without saving to HDD with python and OpenCV

I'm getting uploaded files in my Flask framework app. This file is image which I want to process by OpenCV (in python). Saving this uploaded file to HDD first, will slow down whole operation (additional time of saving and loading image with OpenCV).
Is it possible to load image directly from Werkzeug FileStorage object (memory)?
EDIT: I think you might be able to use FileStorage.stream as input to your OpenCV logic—it's a file like object; if that doesn't work, see below. (See werkzeug.datastructures.FileStorage.stream)
Since FileStorage itself doesn't seem to be a file-like object, what you can do is save() it into one:
from cStringIO import StringIO
inmem_file = StringIO()
file_storage.save(inmem_file) # save to memory
inmem_file.reset() # seek back to byte 0, otherwise .read() will return ''
use_with_open_cv(inmem_file)
This is assuming OpenCV can work with arbitrary file-like objects, not just objects representing to real files.

Extending a PIL decoder

I have a file which contains a single image of a specific format at a
specific offset. I can already get a file-like for the embedded image
which supports read(), seek(), and tell(). I want to take advantage
of an existing PIL decoder to handle the embedded image, but be able to
treat the entire file as an "image file" in its own right.
I have not been able to figure out how to do this given the
documentation
available and was wondering if anyone had any insights as to how I could
do this.
The relevant chapter of the docs is this one and I think it's fairly clear: if for example you want to decode image files in the new .zap-format, you write a ZapImagePlugin.py module which must perform a couple things:
have a class ZapImageFile(ImageFile.ImageFile): with string attributes format and format_description, and a hook-method def _open(self) (of which more later);
at module level, Image.register_open('zap', ZapImageFile) and Image.register_extension('ZAP', '.zap')
The specs for the _open method are very clearly laid out in the chapter -- it must read image data and metadata from open binary file-like object self.fp, raise SyntaxError (or another exception) ASAP if it detects that the file's not actually in the right format, set at least self.size and self.mode attributes, and in order to allow reading the image, also self.tile, a list of tile descriptors again in the format specified in that chapter (including the file-offset, which you say you know, and a decoder -- if the raw or bit decoders, documented in the chapter, don't meet your needs, the chapter recommends studying the sources of some of the many supplied decoders, such as JPEG, PNG, etc).
What I did to solve this was to derive from the ImageFile.ImageFile child belonging to the embedded format instead of ImageFile.ImageFile directly. Then in _open() I replaced self.fp with the file-like to the embedded image, and called the parent's _open(). I can't say that I'm particularly happy doing it this way, but it seems to have worked.

Categories