raspberrypi / picamera2

New libcamera based python library
BSD 2-Clause "Simplified" License
891 stars 188 forks source link

JPEF or DNG images as buffers #916

Open dgalland opened 10 months ago

dgalland commented 10 months ago

It may be useful in certain applications to obtain the jpeg or dng image in a buffer rather than writing it to a file. This is not currently possible with the Request or Helpers methods. For example PiDNG convert can return the buffer if filename == "" but not the helper.

davidplowman commented 10 months ago

Hi, does it not work to pass a BytesIO as the "file", a bit like this example? If it doesn't that would probably be a bug as I'm sure it's the intention!

dgalland commented 10 months ago

Yes it probably works for Picamera2 methods but not for Request methods which ask for a fileName. Something like this: while .....
request = picam2.capture_request() array = request.make_array("raw") or "main" convert in a jpeg or dng buffer

davidplowman commented 10 months ago

I'm sorry, I still don't think I've understood what you want. So far as I know, this type of thing should work:

...
request = picam2.capture_request()
data = io.BytesIO()
request.save('main', data, format='jpeg')

Can you be more explicit about what it is that you can't do? Thanks!

dgalland commented 10 months ago

Yes, this should work for a JPG or PNG but not for a DNG ?

davidplowman commented 10 months ago

PiDNG is a third party library (which we're very happy to be able to use, of course), so we would have to talk to the developer in question. I don't expect it would be difficult to fix, but obviously someone has to have the time to get round to it. It might be worth posting on the PiDNG repo, though I don't know if the author is able to monitor it very closely.

As a workaround one can always write to a memory file (in "/dev/shm"). It is a bit cumbersome, but probably gets you many of the benefits.

dgalland commented 10 months ago

Yes but PIDNG is already able to return the buffer if filename=="" But this possibility disappears in the Helper.

This is just a comment because there are workarounds like using shm or calling directly PiDNG by copying the Helper code This is all for experiments. PiDNG is an interesting tool but it should still be noted that it is extremely slow, 100% Python and therefore not possibly multithreaded.

davidplowman commented 10 months ago

Ah, I see. Well, I suppose I might arguably be happier to see PiDNG handle it because modules like PIL, cv2 do, though I'm not particularly averse to putting a wee bodge into save_dng to detect a BytesIO and work round it.

davidplowman commented 10 months ago

Just to double-check, if I'm going to put in a workaround for this, the test case for the bug report is this:

from picamera2 import Picamera2
import io

picam2 = Picamera2()
data = io.BytesIO()
picam2.start()

picam2.capture_file(data, 'raw')
print(data.getbuffer().nbytes)  # prints 0, and it shouldn't

But I believe JPEGs are OK as things stand.

dgalland commented 10 months ago

Hi David, Yes but we would also have to change the Request method def save_dng(self, filename, name="raw"): and also the Helpers ? def save_dng(self, buffer, metadata, config, filename): The most consistent is perhaps to call PiDng with filename="" ??

davidplowman commented 10 months ago

Maybe have a look whether https://github.com/raspberrypi/picamera2/pull/923 fits the bill?

dgalland commented 10 months ago

Yes that looks correct to me, thank you !

cpixip commented 10 months ago

Great! - when will this show up in the official distribution?

davidplowman commented 10 months ago

I'll see about getting another update out in the next week or so. In the meantime, you can always clone the repo or pip install directly from git to get early access.