Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture photo and get image and thumbnail?

Tags:

I cannot believe that I've struggled with this simple problem for hours now, but I cannot get it to run properly. In principle I want this functionality:

The user clicks a button. An ACTION_IMAGE_CAPTURE intent is fired and the default camera app opens. The user takes the photo and returns to my app. My app shows the thumbnail. Clicking the thumbnail opens the image viewer.

Actually pretty simple. And with this guide it seemed like it was a matter of copy and paste: https://developer.android.com/training/camera/photobasics.html. But the devil is in the details.

Currently, it does work, but performance is horrible because I create the thumbnails (in my actual app I show multiple thumbnails for each entry in a RecyclerView) on the fly. I hope there is a simple approach that I overlooked during searching through dozens of Stack Overlow questions.

Ideally, I'd like to fire my ACTION_IMAGE_CAPTURE intent, have the default camera app generate the thumbnail, store the thumbnail and the image in the system's content providers for thumbnails and images and finally get the respective content:// URIs back in onActivityResult(). That would be so nice...

Now, here are the problems I'm facing:

  • The URI I receive when invoking getData() on the resulting intent in onActivityResult() is always null whether or not I give a MediaStore.EXTRA_OUTPUT value along with the invoking intent
  • When omitting the MediaStore.EXTRA_OUTPUT extra I get the thumbnail in form of a bitmap and not as a content:// URI. So, I have to persist the thumbnail myself if I don't want to generate it next time I start my activity.
  • I don't understand why I don't get the thumbnail if I pass the camera a content:// URI to save the image to. I mean, the camera has the image loaded in memory and could easily generate the thumbnail. But instead, I have to load multiple MB from disk again just to generate the thumbnail. That seems like a huge waste even if I save the thumbnail for further usage afterwards.
  • I have read that some camera apps actually do create the thumbnail in any case and make it available to the gallery or something. But it seems not to be standardized.

So, I guess my wish two content:// URIs simply is not how it works. But before I proceed to generate (eventually duplicate) thumbnails myself and persist and cache them in my app I want to ask:

Is there some easy way I'm not aware of? Is it possible to retrieve both, image and thumbnail or do I have to generate the thumbnail myself?

Note: I want to make the photos taken with my app available to the gallery by letting Android add it to the media database. I can't imagine that every app that accesses that media database (like the gallery) creates it's own set of thumbnails, right?

Thanks in advance!

like image 968
Tobias Uhmann Avatar asked Feb 15 '18 12:02

Tobias Uhmann


1 Answers

The URI I receive when invoking getData() on the resulting intent in onActivityResult() is always null whether or not I give a MediaStore.EXTRA_OUTPUT value along with the invoking intent

There is no Uri returned by ACTION_IMAGE_CAPTURE. If you supply EXTRA_OUTPUT, you know where the image is supposed to reside, so go look for it there.

When omitting the MediaStore.EXTRA_OUTPUT extra I get the thumbnail in form of a bitmap and not as a content:// URI.

Correct.

I don't understand why I don't get the thumbnail if I pass the camera a content:// URI to save the image to.

That's not the way the ACTION_IMAGE_CAPTURE protocol is documented. Either you get a full-size photo written to EXTRA_OUTPUT, or you get a thumbnail via the "data" extra, not both.

I mean, the camera has the image loaded in memory and could easily generate the thumbnail.

There is no single "the camera". There are hundreds of camera apps — both pre-installed and user-installed — that might respond to your ACTION_IMAGE_CAPTURE request, across the ~10,000 device models and ~2 billion devices.

Is it possible to retrieve both, image and thumbnail

Not via ACTION_IMAGE_CAPTURE.

do I have to generate the thumbnail myself?

Ask the MediaStore for a thumbnail, perhaps. I haven't played with retrieving images from MediaStore, but AFAIK it prepares thumbnails of images that indexes. However, bear in mind that your request to index (e.g., MediaScannerConnection.scanFile()) is asynchronous. You may need to temporarily manage thumbnails yourself for images that you capture during this run of the app, relying on the MediaStore for all other images.

I can't imagine that every app that accesses that media database (like the gallery) creates it's own set of thumbnails

I would imagine that many apps request the full-size images and let their image-loading library (Glide, Picasso, etc.) scale the image to the desired size.

Who would want to take a photo to only get the thumbnail?

The ACTION_IMAGE_CAPTURE protocol has been around for a decade. In 2008, everything mobile was expensive: CPU, memory, and bandwidth. Even in 2018, in many parts of the world, some of that stuff is expensive, relative to income levels. Just because you want both full-size and thumbnail images does not mean that everybody does.

like image 135
CommonsWare Avatar answered Sep 22 '22 12:09

CommonsWare