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: 3,943
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. Calling CamEx.Initialize causes the Camera object to be initialized as well (you can see it in the code). The Ready event will be raised when the camera is ready. CamEx.Release releases the camera and allows other applications to use it.

2. Which device are you using?
Try to move camEx.StartPreview after CommitParameters. The preview should start again after a picture is taken.

3. Do you mean the device lock screen? You cannot add a shortcut to the lock screen.
 

wheretheidivides

Active Member
Licensed User
Longtime User
1. Calling CamEx.Initialize causes the Camera object to be initialized as well (you can see it in the code). The Ready event will be raised when the camera is ready. CamEx.Release releases the camera and allows other applications to use it.

2. Which device are you using?
Try to move camEx.StartPreview after CommitParameters. The preview should start again after a picture is taken.

3. Do you mean the device lock screen? You cannot add a shortcut to the lock screen.


2) Samsung galaxy s epic 4g (sprint)
3) Yes that is what I meant. To bad would be nice.
 

wheretheidivides

Active Member
Licensed User
Longtime User
Is there a way to record text or a panel/label on top of the picture? Let's say I want to call it "picture 1". I know I can save it as "picture1.jpg", however it is just the picture that is saved. I'd like to add a caption on the bottom of the screen over top of the picture. Maybe this is a Label. That way the text is always on the picture?

and before someone asks why, I'll say I want to take pictures of receipts so at the end of the year I'll have receipts in a directory. That way I can look at the receipts and have info on the picture which is more info than the file name. It's for tax purposes.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
About the continuous focus issue. I tested this code on several devices and it worked properly here:
B4X:
Sub Camera1_Ready (Success As Boolean)
   If Success Then
      camEx.SetContinuousAutoFocus
      camEx.SetJpegQuality(90)
      camEx.CommitParameters
      camEx.StartPreview
   Else
      ToastMessageShow("Cannot open camera.", True)
   End If
End Sub

There might be an issue with this specific device (the camera seems to be a sensitive hardware on some devices).

Is there a way to record text or a panel/label on top of the picture?
Create a global mutable bitmap and canvas. You can then convert the Data array to an image and draw it with the canvas on the bitmap. You will also be able to draw text with this canvas over the bitmap.
 

deantangNYP

Active Member
Licensed User
Longtime User
Cant run the CameraEx example.

Not able to run the CameraEx Example. Got the following compilation error.
Please advise. Thanks.
:sign0085:
-------------------------------------------------------
Compiling code. Error
Error parsing program.
Error description: Unknown type: r
Are you missing a library reference?
Occurred on line: 211
Dim width01 = r.GetField("width") As Int
-------------------------------------------------------
 

EddyW

Member
Licensed User
Longtime User
@wheretheidivides

i think you are looking for this command (this add the text copyright to the photo)
Canvas1.DrawText("Copyright", 15,15, Typeface.DEFAULT_BOLD, 12, Colors.Red, "LEFT")

look at this page how to init and save the photo after you add the text.
Basic4android - Drawing (Core)
 

deantangNYP

Active Member
Licensed User
Longtime User
@deantangNYP, you should add a reference to the Reflection library (you will need to download it from the forum).

Hi Erel, It was already added. But the error is still there.
Tks.
 

Attachments

  • Capture.JPG
    Capture.JPG
    11.5 KB · Views: 299
Last edited:

Eduard

Active Member
Licensed User
Longtime User
CameraEx class wraps the Camera object and using reflection and other code it extends its functionality.

[*]Preview images and saved images orientation will match the device orientation (all orientations are supported)

Hi Erel,

I tested the saved image orientation om my phone. It doesn't match device orientation. The jpeg image is only correct if I take the picture in landscape. If I hold my phone in portrait while taking an image the image is rotated 90 degrees.

B4X:
Sub Camera1_PictureTaken (Data() As Byte)
   Dim filename As String = "1.jpg"
   Dim dir As String = File.DirRootExternal
   
   camEx.SavePictureToFile(Data, dir, filename)
   
'start test:
      Dim p As Panel
      p.Initialize("")
      Activity.AddView(p,0,0,100%x,100%y)
      p.SetBackgroundImage(LoadBitmapSample(dir,filename,100%x,100%y))
      Msgbox("","Not OK!")
      p.RemoveView
'end test
   
   
   
   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(dir, filename))
   Phone.SendBroadcastIntent(i)
   ToastMessageShow("Picture saved." & CRLF  & "File size: " & File.Size(dir, filename), True)
End Sub

Tested with your b4a example and extra code above. Lib v2.10

Could you provide a fix for this?
 

wheretheidivides

Active Member
Licensed User
Longtime User
Then rotate the picture 90 degrees. Here's some code if you can figure it out.

B4X:
cub activity create

ExpPicFilepath = "/Saved/PDTK/Pics/"

'---------------------------------------------
'Assign chips-16.png to bmp (used later in pop up for date dialog box)

   Bmp_Chips16.Initialize(File.DirAssets, "chips-16.png") 

'----------------------------------------------------------
''make small picture big 5050
   Pic5000SmallBox.Initialize(File.DirAssets,"chips-16.png")
   PicExpDBThumb5 'SR
   
   Panel5099.Enabled = False
   Panel5099.Visible = False
   Panel5099.SendToBack
end sub
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Pic5000SmallBox.Initialize(File.DirRootExternal, YearFilepath & ExpPicFilename)
PicExpDBThumb5 'SR
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Sub PicExpDBThumb5 
'---------------------------------------------------
'show picture in Expense DB thumbnail.  correct aspect ratio (width is longer than heigth here in thumbnail)
   AspectRatio = Pic5000SmallBox.Width/Pic5000SmallBox.Height
   
   IVW5 = ImageView5071BoxPic.Height * AspectRatio
   IVH5 = ImageView5071BoxPic.Height
   
   ImageView5071BoxPic.SetLayout(0, 0, IVW5, IVH5) ' w h
   ImageView5071BoxPic.Bitmap = Pic5000SmallBox

'---------------------------------------------------
End Sub


Sub Button5092RL_Click
'---------------------------------------------------
'rotate large 90 degrees
   Panel5099.SetLayout(0, 0, 100%x, 100%y)
   ImageView5099.SetLayout(0, 0, 100%y * AspectRatio, 100%y)'w h
   
   ImageView5099.Bitmap = RSIE.Rotate(Pic5000SmallBox, 90)
end sub
 

Eduard

Active Member
Licensed User
Longtime User
Then rotate the picture 90 degrees. Here's some code if you can figure it out.
I don't understand how rotating an image view is supposed to be a solution. Rotating the image view does nothing with the saved jpeg.

The orientation of the jpeg image saved by the camera lib is wrong. It should match the device orientation. It should be fixed in the camera lib.
 

Eduard

Active Member
Licensed User
Longtime User
Try to open the saved file with another image viewer (or in the desktop). You will see that it shows correctly.

Some devices set the ORIENTATION header in the jpeg EXIF metadata instead of actually rotate the image. You can use JpegUtils to find the correct orientation and then show it correctly.

THANK YOU. The two programs I choose to test it didn't support orientation header as well (Windows photo viewer and File Expert App). :BangHead:

In some other programs it indeed shows correctly. :eek:

And after opening it in the Gimp It indeed says it has such EXIF data.

I'm really glad it's not a bug.

So what you are saying I should make a sub, let's name it "LoadBitmapSample2" that loads the sample of the image and rotates it depending on the EXIF data?

There isn't by the way a standard solution for this? Everybody should use this I'm I right?
 

Eduard

Active Member
Licensed User
Longtime User
I will add a method to CameraEx to load Jpeg images with the correct orientation.

I've created the sub below because pictures taken with another camera app should display correctly too. The default camera app of Samsung Galaxy S2 for example saves jpeg with orientation as well. I just tested this. All images have orientation "1" or "6"

I would suggest to add the method to LoadbitmapSample2 instead of CameraEx. I'll use code below instead of LoadbitmapSample. I can't have that some images are rotated on some devices, and the same image displayed correct on other ones in my App.


B4X:
Sub LoadbitmapSample2(Dir As String,Filename As String,MaxWidth As Int,MaxHeight As Int,AutoRotate As Boolean) As Bitmap
   Dim bm As Bitmap
   bm=LoadBitmapSample(Dir,Filename,100%x,100%y)
   If AutoRotate Then
      Dim bm2 As BitmapExtended
      Dim exifdata1 As ExifData
      Try
         exifdata1.Initialize(Dir,Filename)
         'http://sylvana.net/jpegcrop/exif_orientation.html
         ' 1) transform="";;
         ' 2) transform="-flip horizontal";;
         ' 3) transform="-rotate 180";;
         ' 4) transform="-flip vertical";;
         ' 5) transform="-transpose";;
         ' 6) transform="-rotate 90";;
         ' 7) transform="-transverse";;
         ' 8) transform="-rotate 270";;
         Select Case exifdata1.getAttribute(exifdata1.TAG_ORIENTATION)
         Case exifdata1.ORIENTATION_ROTATE_180 '3
            bm=bm2.rotateBitmap(bm,180)
         Case exifdata1.ORIENTATION_ROTATE_90 '6
            bm=bm2.rotateBitmap(bm,90)
         Case exifdata1.ORIENTATION_ROTATE_270 '8
            bm=bm2.rotateBitmap(bm,270)
         End Select
      Catch
      End Try
   End If
   Return bm
End Sub
 
Last edited:

coslad

Well-Known Member
Licensed User
Longtime User
Hi Erel

I have a problem with the focus .

I have installed the sample onto two devices :


ZP900 : Zopo device , an 5.3" dual sim chineese
Galaxy S

On the Zp900 the focus go perfect , afert 2 second the device reset the focus even though in the class misses the SetContinuousAutoFocus function

The Galaxy s does't set the focus.

So i have added the sub function : SetContinuousAutoFocus and changed the code adding camEx.SetContinuousAutoFocus before camEx.CommitParameters

But nothing change.

It is not a hardware problem , because with the system camera app the focus is set correctly.

Is there a way to reset manualy the focus ?

Please solve this problem.

Thanks


Edit:


At the moment i have solved using ACL lib ,and on the galaxy s when i need the set the focus , i sent the camera1.FocusMode="AUTO" command and the camera re set the focus.

But i would like to use CameraEx

Edit2:

Is there a way to use system camera to take picture a send the image directly to my application ?
 
Last edited:
Status
Not open for further replies.
Top