I want to write an activity that:
Shows the camera preview (viewfinder), and has a "capture" button.
When the "capture" button is pressed, takes a picture and returns it to the calling activity (setResult() & finish()).
Are there any complete examples out there that works on every device? A link to a simple open source application that takes pictures would be the ideal answer.
My research so far:
This is a common scenario, and there are many questions and tutorials on this.
There are two main approaches:
Use the android.provider.MediaStore.ACTION_IMAGE_CAPTURE event. See this question
Use the Camera API directly. See this example or this question (with lots of references).
Approach 1 would have been perfect, but the issue is that the intent is implemented differently on each device. On some devices it works well. However, on some devices you can take a picture but it is never returned to your app. On some devices nothing happens when you launch the intent. Typically it also saves the picture to the SD card, and requires the SD card to be present. The user interaction is also different on every device.
With approach 2 the issues is stability. I tried some examples, but I've managed to stop the camera from working (until a restart) on some devices and completely freeze another device. On another device the capture worked, but the preview stayed black.
I would have used ZXing as an example application (I work with it a lot), but it only uses the preview (viewfinder), and doesn't take any pictures. I also found that on some devices, ZXing did not automatically adjust the white balance when the lighting conditions changed, while the native camera app did it properly (not sure if this can be fixed).
Update:
For a while I used the camera API directly. This gives more control (custom UI, etc), but I would not recommend it to anyone. I would work on 90% of devices, but every now and again a new device would be released, with a different problem.
Some of the problems I've encountered:
Handling autofocus
Handling flash
Supporting devices with a front camera, back camera or both
Each device has a different combination of screen resolution, preview resolutions (doesn't always match the screen resolution) and picture resolutions.
So in general, I'd not recommend going this route at all, unless there is no other way. After two years I dumped by custom code and switched back to the Intent-based approach. Since then I've had much less trouble. The issues I've had with the Intent-based approach in the past was probably just my own incompetence.
If you really need to go this route, I've heard it's much easier if you only support devices with Android 4.0+.
With approach 2 the issues is stability. I tried some examples, but I've managed to stop the camera from working (until a restart) on some devices and completely freeze another device. On another device the capture worked, but the preview stayed black.
Either there is a bug in the examples or there is a compatibility issue with the devices.
The example that CommonsWare gave works well. The example works when using it as-is, but here are the issues I ran into when modifying it for my use case:
Never take a second picture before the first picture has completed, in other words PictureCallback.onPictureTaken() has been called. The CommonsWare example uses the inPreview flag for this purpose.
Make sure that your SurfaceView is full-screen. If you want a smaller preview you might need to change the preview size selection logic, otherwise the preview might not fit into the SurfaceView on some devices. Some devices only support a full-screen preview size, so keeping it full-screen is the simplest solution.
To add more components to the preview screen, FrameLayout works well in my experience. I started by using a LinearLayout to add text above the preview, but that broke rule #2. When using a FrameLayout to add components on top of the preview, you don't have any issues with the preview resolution.
I also posted a minor issue relating to Camera.open() on GitHub.
"the recommended way to access the camera is to open Camera on a separate thread". Otherwise, Camera.open() can take a while and might bog down the UI thread.
"Callbacks will be invoked on the event thread open(int) was called from". That's why to achieve best performance with camera preview callbacks (e.g. to encode them in a low-latency video for live communication), I recommend to open camera in a new HandlerThread, as shown here.
Related
I want to configure front and back both cameras into Android camera2 API, to take pictures and videos from both cameras simultaneously, I have created 2 texture views , when ever I am opening one camera (front or back) my code is working fine but whenever I am trying to open both cameras simultaneously , code is breaking upon creating session, I am getting cameraAccessException :configure stream : method not implimented.
I want to save both front and back camera captured images as one image and both video as one video.
Guys it will be very much helpful if you can put some sample code or some sample link.
i am using one plus 6, i recently downloaded an app "Dual camera fron back Camera", by using this i am able to capture image from front and back both camera on the same time, so if somebody want to suggest for no hardware support, i think it may be valid for other phones but for my case i think i am missing something in coding, till now from google search it looks like there is some problem with session creation for second camera, i debugged my code, during creation of second camera session it fails so if you have any idea about that, please share.
Thanks
Rakesh
The camera API is fine with it, but most Android devices do not have sufficient hardware resources to run both cameras at once, so you will generally get an error trying to open the second camera.
Both image sensors are typically connected to the same image signal processor (ISP), and that ISP can only operate one camera at a time. Some high-end devices have ISPs with multiple processing pipelines which can in theory run more than one camera at a time, but they often require using multiple pipelines to handle advanced functionality or very high resolutions for the main (back) camera.
So on those devices, multiple cameras may be usable at once, but not at maximum resolution or other similar restrictions.
Some manufacturers include multi-camera features in their own camera app, since they know exactly what the limitations are and can write application code to work within them. They may not make multi-camera available to normal apps, due to concerns about performance, thermal limits, or just lack of time to verify more than the exact use case they implement in their own app.
The Android camera API does not currently have a way to query if multiple cameras can be used at once, or if they can be, what the restrictions are. So the only thing you can do is try, and handle the errors in case that isn't feasible.
Is it possible to broadcast the android camera preview into 2 different SurfaceView controls at the same time? I have seen some apps that show effects into different previews in real-time, how do they achieve that? I read about the TextureView, is this the view to use? where can I find examples of multiple simultaneous camera previews?
Thanks
Well, as they answered in this question, I downloaded the grafika project and revised the "texture from camera" example.
In the RenderThread is a Sprite2d atribute called mRect.
I just make another instance called mRect2, and configuired it with the same parameters that mRect has, except the rotation, I put it to the double:
mRect.setRotation(rotAngle);
mRect2.setRotation(rotAngle*2);
This is the result
There is still a lot of code to understand, but it works and seems a very promising path to continue by.
I don't think that it is possible to independently open 2 camera previews at the same time, as the camera is treated as a shared resource. However, it will be possible to draw to multiple SurfaceViews which is what the apps you describe do.
I have doing a basic object detection on the camera preview screen in Android (greater than 3.2). For the devices which do not support processing on preview screen, I am buffering the preview screen, processing it and clearing the buffer. This part is working as desired.
What I now want is this app to run in the background while any other app is running in the foreground. I am using android service and am able to run a small test app in the background. However my concern is with the camera preview app.
I don't want to display the preview screen but use the preview screen information for processing. This might be too much to ask, but I wanted to know if this is even possible. I came across this link which shows some hope. Basically I want to process the video (preview) stream without displaying it on the screen. If this is doable, then I can think of putting this app in the background and some other app in the foreground.
Unfortunately I won't be able to share the code, however it is the standard logic of creating a surface view and starting the preview.
I would really appreciate any insight into this.
Check comments here.Basically he opens camera hardware, set preview callback and do startpreview without setting the previewDisplay (this might not work on every device). You can try this from your background service. All this will work if your foreground doesn't access the camera app. Please update this if it works. I am interested to know.
If I run this demo on the HTC Hero (CyanogenMod 6.1.0) I get a RuntimeException from the Camera.startPreview() method.
This seems to be the same problem described here:
Android Camera will not work. startPreview fails
In other words, you need to switch the width and height around when setting the preview size. Indeed this works but would then break the demo on other devices.
Now, I understand the purpose of the demo is to show how to get a Camera preview up and running (and so this problem is beyond its scope) but I'm wondering if there is a clean workaround for this since I don't want to put "if HTC_HERO" style logic in my code (anyway, I'm sure other devices will have similar behaviour)?
One hack might be to catch the exception and then re-invoke the setPreviewSize() method with swapped params, but I'm hoping to find a nicer way.
I don't want to put "if HTC_HERO" style logic in my code (anyway, I'm sure other devices will have similar behaviour)?
To some extent, that is inevitable, if you are trying to reach 100% of devices running 100% of arbitrary ROM mods, because bugs will abound.
One hack might be to catch the exception and then re-invoke the setPreviewSize() method with swapped params, but I'm hoping to find a nicer way.
In theory, there should be some universal preview size code that determines the right size and configures the SurfaceView accordingly. If the code of the AOSP camera app is any indication, this code will be massive, and it's still unlikely to work everywhere (e.g., off-spec devices or ROM mods violating whatever assumptions that the authors of the "universal" solution considered).
You may wish to examine projects like ZXing's Barcode Scanner and see how they approach the problem.
so, the way I read the documentation, using EXTRA_OUTPUT tells the camera to save the file in a specific location. That's great, but it also says to get a full size image. That's not so great.
How can I get just a small image but still specify the filename?
After trying to work with the built-in Camera activity for some time now I can advise you not to expect anything good from it because:
built-in activity differs from version to version. For example in 2.2 emulator it even crashes when you try to take a (dummy) picture.
Camera activity on real devices like Samsung Galaxy S is different, i.e. it not just looks different, it has different code and set of bugs.
Original built-in Camera activity has CROP feature, but it is not part of the public API and thus it is not good idea to use it.
So far I fount that to be safe when working with camera I need to:
- create my custom camera activity that misses the fancy stuff like filters, etc but is more configurable (I don't have it yet). I've tried to find third party Camera App but every one of them seems to be targeted at normal users not developers, i.e. has many "cool" features but it is slow / bloated / buggy / has bad UI.
- create thumbnail images by myself outside of the Camera activity (for more control).
I really hope that I am missing something here and someone will correct me in the comments with appropriate solution...
I ended up just dealing with the large images by always scaling on the read. It would have been nice not to have to do that as I read in more than one place, but ...oh well...
problem solved, although far from elegant.