B4A Library [Class] CameraEx - Extends the camera library functionality

Status
Not open for further replies.
Example based on B4XPages: https://www.b4x.com/android/forum/threads/b4x-b4xpages-barcode-reader.120417/#content

CameraEx class wraps the Camera object and using reflection and other code it extends its functionality.

CameraEx class requires Android 2.3+ and depends on Camera library v2.20+
CameraEx features:
  • Easily open the back or front camera
  • Preview images and saved images orientation will match the device orientation (all orientations are supported)
  • Gives access to Camera.Parameters native class (flashmode, picture size, effects and other settings)
  • Includes methods to convert preview images to JPEG and to save the taken pictures.
  • It should be simple to add more methods to this class

SS-2012-11-28_12.18.31.png


See this page for the constant values and other possible methods:
https://developer.android.com/reference/android/hardware/Camera.Parameters.html

Note that you should call CommitParameters after changing one or more parameters.

CameraExClass module is included in the attached example.

V1.30 is attached - Includes various new methods.

v1.20 - Includes all the various posts in this thread as well as AutoFocusAndTakePicture method which first calls AutoFocus and then takes a picture (if AutoFocus was successful).

Edit (06/2018): A new version was uploaded with targetSdkVersion set to 26.
 

Attachments

  • CameraEx.zip
    13.2 KB · Views: 4,324
Last edited:

imgsimonebiliato

Well-Known Member
Licensed User
Longtime User
Hello,
I need to upload a photo with smb.uploadfile(INPUSTREAM...).
How can I return an InputStream directly from the event camera_PictureTaken?
 

Jorge Juarez

New Member
Licensed User
Longtime User
Hello there , thank you all for everything I 've learned , and almost always look at the forums to clear my doubt , but this time , I need a lot of valuable help, I am trying to record in sqlite for right through a variable " Dim act_imagen1 () As Byte " photography taken but I can not do it , someone who can help me please .
Dim ruta As String
If File.ExternalWritable Then
ruta = File.DirRootExternal & "/" & "ACTIV"
Else
ruta = File.DirInternal & "/" & "ACTIV"
End If

Sub Camera1_PictureTaken (Data() As Byte)

Dim aleatorio As Int
aleatorio = Rnd(111,3333)
Variables.aleatoriofoto1 = aleatorio

'Dim filename As String = "1.jpg"
Dim filename As String = Variables.aleatoriofoto1 & ".png"
'Dim dir As String = File.DirRootExternal
Dim dir As String = ruta & "/" & "DCIM"
'ok
camEx.SavePictureToFile(Data, dir, Variables.aleatoriofoto1& ".png")
camEx.StartPreview 'restart preview



'send a broadcast Intent To the media scanner To force it To scan the saved File.
Dim Phone As Phone
Dim i As Intent
i.Initialize("android.intent.action.MEDIA_SCANNER_SCAN_FILE", _
"file://" & File.Combine(ruta & "/" & "DCIM", Variables.aleatoriofoto1 & ".png"))
Phone.SendBroadcastIntent(i)


'ToastMessageShow("Picture saved." & CRLF & "File size: " & File.Size(dir, filename), True)
'ok
pic1.SetBackgroundImage(LoadBitmapSample(dir, Variables.aleatoriofoto1 & ".png",100,100))

'error

Dim InputStream1 As InputStream
InputStream1 = File.OpenInput(dir, Variables.aleatoriofoto1 & ".png")

Dim OutputStream1 As OutputStream
OutputStream1.InitializeToBytesArray(1000)

File.Copy2(InputStream1, OutputStream1)

Dim Buffer() As Byte
Variables.act_imagen1 = OutputStream1.ToBytesArray
AceptFoto.Enabled=True

End Sub
 

Jorge Juarez

New Member
Licensed User
Longtime User
This is the error can not be saved in the database , help please:


opciones_vvvvvvvvvvvvvvvvvvvv7 (java line: 315)
java.lang.IllegalStateException: get field slot from row 0 col 0 failed
at net.sqlcipher.CursorWindow.getString_native(Native Method)
at net.sqlcipher.CursorWindow.getString(CursorWindow.java:382)
at net.sqlcipher.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at android.database.CursorWrapper.getString(CursorWrapper.java:114)
at anywheresoftware.b4a.sql.SQL$CursorWrapper.GetString(SQL.java:355)
at actividades.cymez.opciones._vvvvvvvvvvvvvvvvvvvv7(opciones.java:315)
at actividades.cymez.opciones._activity_create(opciones.java:264)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at actividades.cymez.opciones.afterFirstLayout(opciones.java:89)
at actividades.cymez.opciones.access$100(opciones.java:16)
at actividades.cymez.opciones$WaitForLayout.run(opciones.java:74)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
java.lang.IllegalStateException: get field slot from row 0 col 0 failed
 

tdocs2

Well-Known Member
Licensed User
Longtime User
Greetings, all.

At the risk of being redundant, this class significantly enhances the Camera Lib. - not only for the many features it offers, but because it is more robust and reliable. Two questions:

1. What I do not understand (and I know I can change it), is why Focus in the Class is tied to takepic. See code:

B4X:
'Calls AutoFocus and then takes the picture if focus was successfull.
Public Sub FocusAndTakePicture
    cam.AutoFocus
End Sub
Private Sub Camera_FocusDone (Success As Boolean)
    If Success Then
        TakePicture
    Else
        Log("AutoFocus error.")
    End If
End Sub

2. How exactly would I test if the device camera has autofocus (as opposed to nothing other than the log error on trying to focus)?

Thank you.

Sandy
 

tdocs2

Well-Known Member
Licensed User
Longtime User
Thank you, Erel.

Best regards.

Sandy

PS: BTW, I have tested the ExClass in a plethora of devices and the ExClass seems to handle all possible conditions for my intended use while the Camera Lib by itself was killing the app. Truly, industrial strength.
 
Last edited:

Nostrildumbass

Member
Licensed User
Longtime User
How can I store the picture in PictureTaken into a Bitmap object? I had it working with the standard camera library via an output stream (I have since lost the few lines I had that had this working), and I was able to place the Bitmap into an ImageView as well.
 

canalrun

Well-Known Member
Licensed User
Longtime User
I wrote a library function to do this:

B4X:
Public Sub BytesToBmp(Data() As Byte) As Bitmap
  Dim bm As Bitmap
  Dim ips As InputStream
 
  ips.InitializeFromBytesArray(Data, 0, Data.Length)
  bm.Initialize2(ips)
 
  ips.Close
 
  Return(bm)
End Sub

Here's the top of my PictureTaken subroutine that uses this code:

B4X:
Sub Cam1_PictureTaken(Pic() As Byte)

  Dim bmp As Bitmap

  bmp = MyUtils.BytesToBmp(Pic)

.....

Barry.
 

Nostrildumbass

Member
Licensed User
Longtime User
Tha
I wrote a library function to do this:

B4X:
Public Sub BytesToBmp(Data() As Byte) As Bitmap
  Dim bm As Bitmap
  Dim ips As InputStream

  ips.InitializeFromBytesArray(Data, 0, Data.Length)
  bm.Initialize2(ips)

  ips.Close

  Return(bm)
End Sub

Here's the top of my PictureTaken subroutine that uses this code:

B4X:
Sub Cam1_PictureTaken(Pic() As Byte)

  Dim bmp As Bitmap

  bmp = MyUtils.BytesToBmp(Pic)

.....

Barry.

Thanks so much. I did get it working with what you provided. The Bitmap is showing in my ImageView, but it is turned clockwise 90 degrees. If I take the photo in landscape mode (my app is going to be 100% portrait mode for now) it loads appropriately in the ImageView. I see that the CameraEx class has a SetDisplayOrientation sub, but I'm not really sure how it works or what to do to correct what I'm seeing.

To clarify what I'm trying to do here: my app has a "SignUp" Activity with an ImageView and Global_Process Bitmap. When you tap that ImageView, it starts my "CameraService" Activity (contains a full screen panel with some buttons) which then works with the CameraEx class and puts the PictureTaken result into the Bitmap. The camera closes, bringing us back to the SignUp Activity with the photo that was just taken loaded in the ImageView.
 

canalrun

Well-Known Member
Licensed User
Longtime User
but it is turned clockwise 90 degrees

Image rotation seems to be the $64,000 question.

I have looked at the device orientation, compared that with the image orientation reported by CameraEX, and even examined the Exif information of the image written to a file. Several times I think I have gotten it correct, but then someone comes back to me and says: "the image is rotated".

Maybe someone has figured out the correct solution???

Barry.
 

Nostrildumbass

Member
Licensed User
Longtime User

Nice! I get the feeling that this will work. I just need to adjust it a bit because I am not saving my photo; I am grabbing it straight out of the PictureTaken event as (I believe) a Byte object.

Another minor issue I'm seeing is when I switch camera (via a button on my preview panel; I have the front camera as the default) and take a picture with the rear camera, the picture is not being displayed in my ImageView, however it works fine with the front camera even after switching between front and rear several times.

Edit: Scratch that... here's what I did and it seems to be working! It was very simple. I only declared a BitmapExtended object and returned bm2.rotateBitmap(mybitmap, -90)). This might not be the ideal way to handle this (different devices may behave differently) but it'll do for now.

B4X:
Public Sub BytesToBmp(Data() As Byte) As Bitmap
  Dim bm As Bitmap
  Dim ips As InputStream
  ips.InitializeFromBytesArray(Data, 0, Data.Length)
  bm.Initialize2(ips)
  ips.Close
 
  Dim bm2 As BitmapExtended
  Return(bm2.rotateBitmap(bm,-90))
End Sub
 
Last edited:

NeoTechni

Well-Known Member
Licensed User
Longtime User
Is there a way to use BytesToBmp on the preview image (camera_preview(Data() As Byte)) ? I'd like to handle the image in real time.
I tried and I just get an error :/
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
I use that now, but it:
-takes the full resolution of the camera instead of a size I specify
-converts to jpeg

Both steps slow it down considerably so you can't do much in real time
 
Status
Not open for further replies.
Top