Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camera API: Cross device issues

I'm developing a camera app basically as part of a messaging app to attach images etc. The app needs to work for >= SDK 2.2 and:

I can't use the default Android Camera as much as I'd love to because:

  1. The nature of the app dictates that the image should not be saved to disk ever and some OEMs (Samsung) love to do this without giving you a choice.

  2. I can't call an intent that any other camera app can intercept because then that app could save the image.

My current problem is dealing with the fact that the Android camera apparently hates being in portrait orientation. Specifically, after some digging I'm monitoring the display and, on rotation, calling setDisplayOrientation(90). This works but the surfaceview dimensions need to be altered also and this must be done within supported dimensions or the parameter setting crashes the app.

I'm doing this with another SO snippet I found here (the getBestPreviewSize() method) but it has one glaring problem that I can't believe I haven't found anyone else having.

Part of the takePicture lifecycle involves calling the PostView picture callback. This is what shows the still image of the current paused SurfaceView image that will be returned via byteArray to the raw and/or jpeg callback. My problem is, this image is still skewed on a handful of seemingly random test devices! So the behavior is a user sees a dynamic camera image in perfect 4:3 aspect ratio until they take the picture and the image they are presented with is squished. Note that the byte array itself is correct and when I construct the Bitmap at the messaging end point it shows up fine but this is still a problem.

I can't see how I can alter the still image display at this point. Can anyone help me with this?

like image 938
Andrew G Avatar asked Oct 04 '12 22:10

Andrew G


People also ask

What is the permission for using the Camera in Android?

On your phone, open the Settings app. Tap Privacy. Turn off Camera access or Microphone access.

What is Camera to API?

Both CameraX and Camera2 support Android 5.0 (API level 21) and higher. Camera2 is the low-level Android camera package that replaces the deprecated Camera class. Camera2 provides in-depth controls for complex use cases, but requires you to manage device-specific configurations.


2 Answers

Android camera system is a mess. And beind soldered to motherboard, camera chip is not going to like portait application - all the callbacks spill out data in camera orientation (buffer you receive is actually shared memory piece with native camera app) - if you like to display it while your application is in portait mode, you will have to flip this data over xy.

Instead of showing image on the surface view used by camera, I would overlay it with transparent ImageView and draw my bitmap there.

You may (hopefully) find some inspiration in out javaocr project where android deamon work in portrait mode and draw bitmaps over live preview. (please checkout from git, as it is being released now and I'm struggling with git and maven, see demos directory)

like image 100
Konstantin Pribluda Avatar answered Oct 09 '22 05:10

Konstantin Pribluda


I suspect your problem is at a couple different levels.

Sensor Mount

First, the camera sensor is mounted different on every device. Google has boiler plate code for getting that orientation and setting the correct rotational value to correct it here and it is good down to API 8.

AR Correction

The second issue is obviously that the preview frames aren't the same aspect ratio as the screen. You can use this post to solve that. The surfaceview dimensions have no relation to the best preview size, those values do not have to match - in fact, that your AR is messed up proves that they don't match.

Preview Frame Size != Picture Size

Finally, when you take a picture using takePicture, the size of the picture is completely independent of the size of your preview frame. Use the following to query and set the preview frame size: setPreviewSize() / getSupportedPreviewSizes()

Use the following to query and set the picture size (from takePicture()): getSupportedPictureSizes() / setPictureSize()

Some devices you may get lucky on and the defaults for pictures and preview frames will be the same. This is not the case on all devices.

Finally, if you want to display the taken picture, you may need to do AR correction on it as well if it's not the same size as your SurfaceView. Alternatively you could draw it to an ImageView and use ScaleType.CENTER_INSIDE to preserve the aspect ratio.

like image 39
Error 454 Avatar answered Oct 09 '22 04:10

Error 454