Camera, preview doesn't show up the second time

Penko

Active Member
Licensed User
Longtime User
Hello all!

I am trying to create an Activity which handles all needs of PictureCapture for my application. A single activity which is called from multiple places and it returns(via CallSubDelayed) the captured picture(the path-to-it).

Capturing works fine, however I have the following problem. I am trying to immitate the design of other applications where you take a picture but it gives you the option to take a new one if you don't like the results.

What doesn't work is - when I take a picture, then click "btnTakeNew", I don't get preview on my panel again. It just gets empty(because I call "clearPanel" method to remove the snapshot when I am going to show the preview again.

A more interesting thing is, no matter I don't get a preview, if I click on the panel, a new image is taken and the new image correspond to the location I've directed my phone to. So the pictures are real but you don't see where you are aiming. It works the first time I open the activity but doesn't work after I don't like the result and go for "Take New"(click the button).

My code pretty much copies the Camera example. I've just added Subs because I hate working with events directly.

B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   
   'Dim out As OutputStream
End Sub

Sub Globals
   Dim camera1 As Camera
   Dim btnTakePicture As Button
   
   Dim came_from As Object
   Dim backSub As String
   
   Dim pnlCameraImage As Panel
   Dim btnOK As Button
   Dim btnTakeNew As Button
   Dim pnlControls As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("layCamera_takephoto")
End Sub

Sub Activity_Resume
   initializeCamera

End Sub

Sub Activity_Pause (UserClosed As Boolean)
   camera1.Release
End Sub

Sub Activity_KeyUp (KeyCode As Int) As Boolean

   If(KeyCode = KeyCodes.KEYCODE_DPAD_CENTER) Then
      TakePicture
   End If

End Sub

Sub selector(sourcePlace As Object)
   came_from = sourcePlace
   
   'initializeCamera
   
End Sub

Sub initializeCamera()

   Activity.Invalidate

   Try
   '   camera1.Release
   Catch
   
   End Try



   Try
      camera1.Initialize(pnlCameraImage, "Camera1")
   Catch
   
   End Try

hideControlsPanel
End Sub

Sub getBack()
   If(backSub = "") Then
      CallSubDelayed(came_from, "getBackWithPicture")
   Else
      CallSubDelayed(came_from, backSub)
   End If
End Sub

Sub Camera1_Ready (Success As Boolean)
   If Success Then
      StartRecording
      'btnTakePicture.Enabled = True
   Else
      ToastMessageShow("Cannot open camera.", True)
   End If
End Sub

Sub Camera1_PictureTaken (Data() As Byte)

   

   'camera1.StartPreview
   Dim out As OutputStream
   out = File.OpenOutput(File.DirRootExternal, "temp.jpg", False)
   out.WriteBytes(Data, 0, Data.Length)
   out.Close
   
   ToastMessageShow("Image saved: " & File.Combine(File.DirDefaultExternal, "temp.jpg"), True)
   
   Dim img As ImageView
   img.Initialize("img")
   img.Bitmap = LoadBitmap(File.DirRootExternal, "temp.jpg")
   
   pnlCameraImage.AddView(img, 0, 0, 100%x, 100%y) ' add a snapshot to the panel.
   
   showControlsPanel ' show the buttons btnOK and btnTakeNew

End Sub

Sub TakePicture()
   camera1.TakePicture ' take the picture
   StopRecording ' stop recording. I think this is handled internally but not sure.
End Sub

' starts the previous of images
Sub StartRecording()
   pnlControls.Visible = False ' hide the btnOK and btnTakeNew controls
   camera1.StartPreview
End Sub

Sub StopRecording()
   camera1.StopPreview
End Sub

Sub showControlsPanel()
   pnlControls.Visible = True
End Sub

Sub hideControlsPanel()
   pnlControls.Visible = False
End Sub

Sub btnTakeNew_Click()
   zCommon.clearPanel(pnlCameraImage) ' clear the snapshot
   StartRecording ' start new previews
End Sub

Sub btnOK_Click
   getBack ' we like the result, go back to the calling Activity
End Sub
Sub pnlCameraImage_Click

If(pnlControls.Visible = True) Then ' this will disable picture taking if the controls menu is visible. It is time for decision, not new picture taking.
   Return True
End If

   TakePicture
End Sub
 

Attachments

  • camera_design.jpg
    camera_design.jpg
    27.1 KB · Views: 259

Penko

Active Member
Licensed User
Longtime User
The example code is a little different from what I am trying to achieve. I want to give the users preview of what they are aiming at and when they click the panel, it should take the image. Then, if you click "btnNewImage", the preview should start again(but it should clear the panel from the last result image first) and then show what's the camera seeing in the panel. This is what doesn't work after I start preview again(btnTakeNew). But as I said, if I click the panel, an image is being taken. It's just the preview that doesn't show up. The panel is gray(by default). It happens the second time as it works when I first open this Activity).

The function you asked about fetches trough all views on the panel and removes them. This is used to remove the previous snapshot of the image we have taken.
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
But Penko, removing views from your pnlCameraImage panel, doesn't remove also the preview? I didn't check your code thoroughly, but I suppose there would be a subroutine for representing this view.
 
Upvote 0

Penko

Active Member
Licensed User
Longtime User
I am cleaning the panel before calling .StartView again.

If I remove the call to the clearPanel function, then the panel keeps the frozen snapshot(the taken picture from the previous preview).

To summarize the problem, if I take a picture, I don't like it, click btnTakeNew, I don't get live previous from what the Camera sees. However, clicking the panel(this triggers my TakePicture sub), takes an image which is real(If I face my phone to my Coca-Cola bottle, I don't see any preview - so I am blind while taking, but if I click the panel, an actual picture of the coca cola is being taken and shown to me).

So, to say it again, I just don't get live previews the second time I start the process(or any next time).
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Where should you see the preview? I mean, at which panel?

Perhaps you should release the camera and then reinitializing with takeNew?
 
Last edited:
Upvote 0

Penko

Active Member
Licensed User
Longtime User
pnlCameraImage.

Edit:

I cracked this in a very simple way(I had this in mind, but @mc73 gave me an additional brave idea, as always).

Erel, thanks to you too.

Here is what we do:

at the place we store the image - just call Camera1.Release

Then, the click event of "btnTakeNew" should do this:

B4X:
Sub btnTakeNew_Click()
   zCommon.clearPanel(pnlCameraImage) ' clear the snapshot
   initializeCamera
End Sub

So, we make the camera busy only until we take the photo, then release it. If we are to take a new one, just initialize it again.

I am not sure how reliable this is but it does exactly what what supposed.
 
Last edited:
Upvote 0
Top