Android Tutorial Camera2 - Still images and videos

Status
Not open for further replies.
Camera2 library is based on the Camera2 API introduced in Android 5 (API 21).
It is designed to work together with CamEx2 class.
It is supported by B4A v7.3+. The library will be included as an internal library in the next update.

Both image capturing and video recording are supported.
CamEx2 class is built to be extended. Camera2 native API is huge.

SS-2017-09-14_17.27.38.png


The configuration steps:

1. Open the camera when the activity is resumed.
2. Prepare the surface and start preview. The preview size and capture size are set at this point.
3. Stop the camera when the activity is paused.

Take pictures with FocusAndTakePicture or TakePictureNow.

Video capturing is done by calling StartVideoRecording and StopVideoRecording.
The surface needs to be recreated after the video is recorded.

TaskIndex

When you open the camera you receive a number called TaskIndex:
B4X:
Wait For (cam.OpenCamera(front)) Complete (TaskIndex As Int)
If TaskIndex > 0 Then
   MyTaskIndex = TaskIndex 'hold this index. It will be required in later calls.
   Wait For(PrepareSurface) Complete (Success As Boolean)
End If
If the value of TaskIndex is 0 then the camera failed to open. Otherwise you need to store it in a global variable and pass it to other camera methods.

The camera can be stopped or reopened while other asynchronous tasks are running. The task index is used to cancel running tasks in such cases.

Notes & tips

- The RECORD_AUDIO is not added automatically as it is only required when recording video. In such case you need to add it with the manifest editor:
B4X:
AddPermission(android.permission.RECORD_AUDIO)

CamEx2 class is is included in the attached example.
It depends on Camera2 v1.10+.

Change log

- V1.32 - Fixes an issue with inconsistent return value from TakePictureNow.
- V1.31 - Changes the behavior of PreviewCropRegion to affect the captured image as well (previously it was inconsistent).
- V1.30 - Fixes an issue with video orientation.
- V1.20
  • Example updated and targetSdkVersion is set to 26. Permissions are handled at runtime.
  • Digital zoom feature. Note that it only affects the preview.
  • Fixed typo in getSupportedVideoSizes method.

New example:
  • Based on B4XPages (there are instructions inside if you want to use it in an Activity module).
  • Preview image is not stretched.
  • Captured image is shown with the correct orientation.
 

Attachments

  • CamEx2.zip
    22.5 KB · Views: 19
Last edited:

rboeck

Well-Known Member
Licensed User
Longtime User
Axon7:
I made an unfiltred log; you see the crash at line 858. I could make four photos, switched to video and after ending of record it crashed.
Sometimes it starts with this message: "Failed to open camera"
Sony Tablets SPG321 and SPG521:
The problem with unknown const 18 i could also find on my sony xperia tablets; it was logged in line 364 of CamEx2 class, release of today. Currently i need one minute of playing to get the message. When starting the app on sony tablet i get always:
--------- beginning of system
--------- beginning of crash
--------- beginning of main
on the older sony tablet the line with crash is the first.
Nexus 5:
Everything works without problems

I hope, this report can bring some 'light' to the CamEx problems...
 

Attachments

  • Axon7 log.txt
    199.7 KB · Views: 791

Erel

B4X founder
Staff member
Licensed User
Longtime User
What happens after this error is printed?

Change the two subs to:
B4X:
Private Sub IntToConst (Int1 As Object, Consts As List) As String
   If Int1 = Null Then Return ""
   Dim i As Int = Int1
   If i >= 0 And i < Consts.Size Then
     Return Consts.Get(i)
   Else
     Log(Consts)
     Log("Unknown const: " & i)
     Return ""
   End If
End Sub

Private Sub IntsToConstsList (Ints As Object, Consts As List) As List
   Dim res As List
   res.Initialize
   If Ints = Null Then Return res
   Dim f() As Int = Ints
   For Each mode As Int In f
     If mode >=0 And mode < Consts.Size Then
       res.Add(Consts.Get(mode))
     Else
       Log(Consts)
       Log("Unknown consts: " & mode)
     End If
   Next
   Return res
End Sub

This way we can find which parameter is unknown.

Change ApplicationError in the starter service to:
B4X:
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
   Log("Application_Error")
   Log(Error)
   Log(StackTrace)
   Return False
End Sub
What happens now?
 

rboeck

Well-Known Member
Licensed User
Longtime User
On Sony i get this result:

** Activity (main) Pause, UserClosed = true **
Ignoring event: camera_surfaceready
Ignoring event: camera_previewcapturecomplete

on Sony SGP521 i could get this results when i click FACE_PRIORITY Button:
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Start success: true
Start success: true
Focus not supported
Picture taken: (Bitmap): 1920 x 1080, scale = 1,00
(ArrayList) [DISABLED, FACE_PRIORITY, ACTION, PORTRAIT, LANDSCAPE, NIGHT, PORTRAIT, THEATRE, BEACH, SNOW, SUNSET, STEADYPHOTO, FIREWORKS, SPORTS, PARTY, CANDLELIGHT, BARCODE]
Unknown consts: 18
(ArrayList) [DISABLED, FACE_PRIORITY, ACTION, PORTRAIT, LANDSCAPE, NIGHT, PORTRAIT, THEATRE, BEACH, SNOW, SUNSET, STEADYPHOTO, FIREWORKS, SPORTS, PARTY, CANDLELIGHT, BARCODE]
Unknown consts: 18
(ArrayList) [DISABLED, FACE_PRIORITY, ACTION, PORTRAIT, LANDSCAPE, NIGHT, PORTRAIT, THEATRE, BEACH, SNOW, SUNSET, STEADYPHOTO, FIREWORKS, SPORTS, PARTY, CANDLELIGHT, BARCODE]
Unknown consts: 18
(ArrayList) [DISABLED, FACE_PRIORITY, ACTION, PORTRAIT, LANDSCAPE, NIGHT, PORTRAIT, THEATRE, BEACH, SNOW, SUNSET, STEADYPHOTO, FIREWORKS, SPORTS, PARTY, CANDLELIGHT, BARCODE]
Unknown consts: 18
(ArrayList) [DISABLED, FACE_PRIORITY, ACTION, PORTRAIT, LANDSCAPE, NIGHT, PORTRAIT, THEATRE, BEACH, SNOW, SUNSET, STEADYPHOTO, FIREWORKS, SPORTS, PARTY, CANDLELIGHT, BARCODE]
Unknown consts: 18

The buttons caption doesn't change to disable.

On Axon 7:

Logger verbunden mit: bc412fa1
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Start success: true
Start success: true
Start success: true
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Surface android.hardware.camera2.params.OutputConfiguration.getSurface()' on a null object reference
at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.onCaptureErrorLocked(CameraDeviceImpl.java:1925)
at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.onDeviceError(CameraDeviceImpl.java:1693)
at android.hardware.camera2.legacy.CameraDeviceUserShim$CameraCallbackThread$CallbackHandler.handleMessage(CameraDeviceUserShim.java:299)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:179)
at android.os.HandlerThread.run(HandlerThread.java:61)
Logger verbunden mit: bc412fa1
--------- beginning of system
--------- beginning of main
(ArrayList) [DISABLED, FACE_PRIORITY, ACTION, PORTRAIT, LANDSCAPE, NIGHT, PORTRAIT, THEATRE, BEACH, SNOW, SUNSET, STEADYPHOTO, FIREWORKS, SPORTS, PARTY, CANDLELIGHT, BARCODE]
Unknown consts: 18

The buttons caption change to all possibilities. Only one crash in 3 minutes.

On Sony Z1 Compact the video and the foto preview is 180° turned; this mobile is nearly out of order...
 

jimmyF

Active Member
Licensed User
Longtime User
Crashed when I tried to switch back from video to still camera.
Focus does not work, nor Scene.

Log file attached:
 

Attachments

  • debugJimmyF.txt
    48.5 KB · Views: 762

rboeck

Well-Known Member
Licensed User
Longtime User
With this version i get only one crash on my old Sony z1 compact. The crashes with axon 7 are away.
Here i still have the problem with "selfie" cam - i get fotos and videos bottom up, the camera on the back is working regular. The routine starter Application_Error was not executed, but i have no idea, why.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Devices with legacy support are more problematic and should probably use Camera instead of Camera2.

I'm unable to reproduce the NullPointerException here, so it is hard for me to fix it.

One thing that worth trying is to add Sleep(500) after each call to CloseSession (put the cursor on CloseSession and click F7 to find where it is called).
 

rboeck

Well-Known Member
Licensed User
Longtime User
What does exactly legacy support mean - how can i know, if a customer is using a legacy device?
 

PhiloSophical

Member
Licensed User
Longtime User
..and to add to post #28 - is there a way to establish this before purchasing a device by understanding some hardware/driver characteristic that is known

post #8 may help - this examples my device as being recognised as "Legacy" - Is there a way of getting this output via a b4a library?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Add this sub to CamEx2:
B4X:
Public Sub getSupportedHardwareLevel As String
   Dim jo As JavaObject = Camera.GetCameraCharacteristics(0)
   Return IntToConst(jo.RunMethod("get", Array(StaticCameraCharacteristics.GetField("INFO_SUPPORTED_HARDWARE_LEVEL"))), SUPPORTED_HARDWARE_LEVEL)
End Sub

You can call it before you open the camera.

It will return one of the following values: LIMITED, FULL, LEGACY, LEVEL_3

The values are described here: https://developer.android.com/refer...cteristics.html#INFO_SUPPORTED_HARDWARE_LEVEL
is there a way to establish this before purchasing a device by understanding some hardware/driver characteristic that is known
I don't think so.
 

rboeck

Well-Known Member
Licensed User
Longtime User
Sorry, there is still some information missing: i copied your code to the camex2 example and get (backtranslated:) unknown member: getcameracharacteristics;
i have tried to add the old camera library, but i didnt help.
 

rboeck

Well-Known Member
Licensed User
Longtime User
Sorry for making problems: can it be, that a new axon 7, Android 7.1, 4k video capturing is in category legacy? (based on CamEx2 v1.15)
 

jimmyF

Active Member
Licensed User
Longtime User
Logger connected to: BlackBerry BBB100-1
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
LEGACY
** Activity (main) Resume **
Start success: true
Start success: true
Start success: true
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Surface android.hardware.camera2.params.OutputConfiguration.getSurface()' on a null object reference
at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.onCaptureErrorLocked(CameraDeviceImpl.java:1925)
at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.onDeviceError(CameraDeviceImpl.java:1693)
at android.hardware.camera2.legacy.CameraDeviceUserShim$CameraCallbackThread$CallbackHandler.handleMessage(CameraDeviceUserShim.java:299)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
So it has legacy support.
Crash occurs when switching back from Video to Still Camera.
Focus button does not get passed OFF then stops responding.
Scene has no effect.
Effect DOES work.
Camera works.
Stopping Video crashes. Message above.
 

KingEdem

Member
Licensed User
Longtime User
Camera2 library is based on the Camera2 API introduced in Android 5 (API 21).
It is designed to work together with CamEx2 class.
It is supported by B4A v7.3+. The library will be included as an internal library in the next update.

Both image capturing and video recording are supported.
CamEx2 class is built to be extended. Camera2 native API is huge.

SS-2017-09-14_17.27.38.png


The configuration steps:

1. Open the camera when the activity is resumed.
2. Prepare the surface and start preview. The preview size and capture size are set at this point.
3. Stop the camera when the activity is paused.

Take pictures with FocusAndTakePicture or TakePictureNow.

Video capturing is done by calling StartVideoRecording and StopVideoRecording.
The surface needs to be recreated after the video is recorded.

TaskIndex

When you open the camera you receive a number called TaskIndex:
B4X:
Wait For (cam.OpenCamera(front)) Complete (TaskIndex As Int)
If TaskIndex > 0 Then
   MyTaskIndex = TaskIndex 'hold this index. It will be required in later calls.
   Wait For(PrepareSurface) Complete (Success As Boolean)
End If
If the value of TaskIndex is 0 then the camera failed to open. Otherwise you need to store it in a global variable and pass it to other camera methods.

The camera can be stopped or reopened while other asynchronous tasks are running. The task index is used to cancel running tasks in such cases.

Notes & tips

- The RECORD_AUDIO is not added automatically as it is only required when recording video. In such case you need to add it with the manifest editor:
B4X:
AddPermission(android.permission.RECORD_AUDIO)

CamEx2 class is is included in the attached example.
It depends on Camera2 v1.10+.


HI Erel,

I would like to superimpose (transparent 30%) date n time on the recording video and snap picture. Please suggest.
 

Croïd

Active Member
Licensed User
Longtime User
CamEx2 v1.15

Hi

a) For the shift of the light with the function "ON_ALWAYS_FLASH", The picture remains dark ! Is there a solution ?

b) Can I use the "Torch" function?
 
Status
Not open for further replies.
Top