CameraX: show captured image and apply effects - android

I am trying to create Android CameraX app where user can take a photo, apply some image processing effects and view the result, without a need to save it to disk. But for me, the most challenging part is to pass the image to another activity where it will be processed.
I could create an Intent and attach the image using PutExtra(). But it would take too much memory and slow down the UI, since intent extras are not recommended to exceed 1 Mbyte. For example, 8MP photo would consume 24 Mb uncompressed and about 1.3 Mb in JPEG format.
Share the image in public class properties - according to Android docs, it's not a reliable way to pass data directly between activities, because the system may create and destroy them at any time.
Okay, let's capture the image into a file to and open it in our second activity. Or just call a built-in camera app to do so. It wouldn't be a problem for couple of images. But if user wants to capture 20-30 of them and more, it will cram the media folder and wear down the device storage.
Which is the best practice to pass image data between activities?

Store the image in your local storage and pass the URI of it as intent between activities because the ram is more costly than storage. This is a way how WhatsApp has exposed its intent to pass the image.
Also regarding multiple captures, you can easily handle it through code in your app.
Helpful Link

I have found a quite simple way: if I don't need more than one instance of certain data, I can declare an application level object (right click in java folder - new - kotlin file - enter name and choose "object"). It is initialised on first access, and stores its properties throughout the application's life. It may also contain methods to read/write/process the data.
In onCaptureSuccess(img: ImageProxy) listener I obtain the image from ImageProxy (it's in JPEG format), decode it with BitmapFactory and assign the Bitmap to object field. In other activity, all to do is to read the Bitmap from the object.

Related

Taking photos and videos in app and sending the data between app components

This question is a bit on the broader side of things so I will not provide any specific code because it will be irrelevant.
I have an app that allows the user to take photos, and hopefully videos in the future. Currently it happens as follows:
The user opens a dialog inside one activity.
The user can choose to take an image, which sends him to a CameraActivity (using CameraX).
The user takes an image, the image is saved locally in the app files and the result code and path to the image are sent to the calling activity.
The dialog overrides onActivityResult and loads the image from the internal storage and displays it.
The user can choose to delete the image or cancel the entire dialog, on both cases the image needs to be removed from the storage.
(The process can happen with multiple images inside the same dialog)
I wanted to ask you if it seems like a reasonable implementation or there are other architectures\android components you would recommend using. More specifically I'm worrying about the time it takes to save the image locally if I will want to increase the quality or do the same process with videos which are much heavier (I've already seen a considerable extra time if I want to save it as png instead of jpeg).
The two improvements to the system that I can think of:
Using something akin to ViewModel for saving the bitmap and having the data available when moving back to the dialog from the camera activity.
Saving the data to the cache instead on the local storage (and only save it to the local storage if the user approves in the dialog).
But I'd like to hear suggestions, are there any particular APIs that I should know about? or a recommended change to the architecture?
The current system will simply be too slow for higher quality images or a video, and I'm not sure how best to improve things and also not make the app too consuming on the resources side.

Take a picture and get bytes without saving on disk

Is it possible to take a picture and get the image as byte array without saving it?
All I want is, take an in memory picture. I don't want to save it. Also i plan to use other camera activity to take the picture (i mean, i don't want to implement my own camera logic)
Please note, I know that I can take a picture, read bytes and delete it. But I am looking if I can avoid this saving and deleting part, instead directly get the image in an in memory byte array.
Is it possible to take a picture and get the image as byte array without saving it?
That is the behavior of the android.hardware.Camera API, the android.hardware.camera2 API, and third-party libraries that simplify those APIs (e.g., Fotoapparat, CameraKit-Android).
i plan to use other camera activity to take the picture
If by "other camera activity", you mean a third-party camera app (e.g., via ACTION_IMAGE_CAPTURE), that will be difficult and unreliable. At best, you could try to use a content Uri pointing to a ContentProvider that you write that only holds onto written streams in memory. I would expect you to run out of heap space. Plus, not all camera apps will support a content Uri for EXTRA_OUTPUT (though they should).

Difference between passing string and images through intents(in term of memory usage)

In my application, I have several images downloaded from the internet and when I click on those images, the images will be pass to an image viewer (a new activity). In term of memory usage, which is the best way to pass the images to image viewer by using intents? Should I pass the url of the images to the image viewer or pass the bitmaps instead?
If you have downloaded images, you must send the "Path" of image where it is downloaded using intent.
From the path received, create a file and make a bitmap of that image.
Actually, there are likely no difference in memory footprint. Bitmap is passed through Intent as Parcelable, and you can dig into Android SDK source code to find out that only link to it is written.
On the other hand, it'll be safer to pass String inside intent in terms of app lifecycle — if the app will be suspended, there can be issues with restoring bitmap from saved intent.

Disabling Android Camera automatic thumbnail

I've seen that Android automatically generates a thumbnail when taking a photo, and saves it as an extra with the key "data". Is it possible to disable that action, as to save space in the device?
I've seen that Android automatically generates a thumbnail when taking a photo, and saves it as an extra with the key "data".
No, it does not. Camera apps may generate thumbnails and put them in a data extra in the Intent used with setResult(). Android, the operating system, does not.
Is it possible to disable that action, as to save space in the device?
I do not know what "space" you think you will "save". That thumbnail is held briefly in system RAM. It is not stored on disk.
If you are a programmer, and if you are writing an Android app, and if you are using an ACTION_IMAGE_CAPTURE Intent with startActivityForResult() to invoke a third-party camera app, then you can include EXTRA_OUTPUT to indicate where you want a full-sized image to be written. According to the ACTION_IMAGE_CAPTURE specification, the data extra is not needed in that case. Some camera apps will then skip that extra.
However, developers of third-party camera apps are welcome to do whatever they want. If they want to create the data extra on every ACTION_IMAGE_CAPTURE request, that is their decision to make, as they are the ones writing the camera apps.

Keep Camera from saving photo

I have an application that captures pictures by dispatching an intent. Upon return of control to the activity, I retrieve the intent, extract the data, transform it into a bitmap and use it in my application. Just some straight forward code.
The pictures taken are subject to some privacy obligations and my application takes care to delete all data. The problem is that all pictures taken by the Camera application seem to automatically be saves into internal storage. I was successful in deleting screenshots taken by the device and by clearing all thumbnails. What remains to be done is keep the Camera application from storing picture in the first place.
The problem as I see it is that I relinquish control to the application and, hence, cannot influence it in any way. I tried launching ACTION_IMAGE_CAPTURE_SECURE but that failed. I would much prefer the approach of keeping the application from storing the image to the approach of having to scan the internal storage location for images and delete them as I tried it and failed.
Note: I have assigned all the right permissions. Should you need code, I will be happy to post it but there is nothing that cannot be found already in other threads. If there is no solution to my preferred approach, how would I go about deleting all images located in the internal storage at DCIM\Camera? Thank you!
If you need to override that behavior, don't take the pictures via intent. Take them yourself, using the android.hardware.Camera API.

Categories

Resources