Integrate Picture-in-Picture with the Xamarin Camera Control - Xamarin C#

This tutorial shows how to integrate picture-in-picture mode for video captured from the device's camera in a C# Xamarin application using the Xamarin Camera Control.

Overview  
Summary This tutorial covers how to integrate picture-in-picture to display live capture video frames in a C# Xamarin application.
Completion Time 15 minutes
Visual Studio Project Download tutorial project (510 KB)
Platform C# Xamarin Cross-Platform Application
IDE Visual Studio 2019, 2022
Development License Download LEADTOOLS

Required Knowledge

Get familiar with the basic steps of creating a project and using the Xamarin Camera Control by reviewing the Add References and Set a License and Integrate Live Capture with Xamarin Camera Control tutorials, before working on the Integrate Picture In Picture with the Xamarin Camera Control tutorial.

Create the Project and Add the LEADTOOLS References

Start with a copy of the project created in the Integrate Live Capture with Xamarin Camera Control tutorial. If you do not have that project, follow the steps in that tutorial to create it.

The references needed depend upon the purpose of the project. For this project, the following NuGet packages are needed:

Set the License File

The License unlocks the features needed for the project. It must be set before any toolkit function is called. For details, including tutorials for different platforms, refer to Setting a Runtime License.

There are two types of runtime licenses:

Edit the XAML and Camera Control Code

With the project created, the references added, and the license set, coding can begin.

In Solution Explorer, open LiveCapturePage.xaml and ensure the following code is added inside the ContentPage.

<ContentPage.Content> 
   <StackLayout> 
      <!--main grid container for everything--> 
      <Grid x:Name="mainGrid" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"> 
         <Grid.ColumnDefinitions> 
            <ColumnDefinition x:Name="c0" Width="*"/> 
            <ColumnDefinition x:Name="c1" Width="*"/> 
            <ColumnDefinition x:Name="c2" Width="*"/> 
         </Grid.ColumnDefinitions> 
         <Grid.RowDefinitions> 
            <RowDefinition x:Name="r0" Height="*"/> 
            <RowDefinition x:Name="r1" Height="*"/> 
            <RowDefinition x:Name="r2" Height="*"/> 
            <RowDefinition x:Name="r3" Height="*"/> 
            <RowDefinition x:Name="r4" Height="*"/> 
            <RowDefinition x:Name="r5" Height="*"/> 
            <RowDefinition x:Name="r6" Height="*"/> 
            <RowDefinition x:Name="r7" Height="*"/> 
            <RowDefinition x:Name="r8" Height="*"/> 
         </Grid.RowDefinitions> 
         <Label x:Name="capturedFrames" Text="Frames Captured: 0" TextColor="Blue" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"/> 
         <namespace:CameraView x:Name="leadCamera" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Grid.RowSpan="7" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/> 
         <Button x:Name="liveCapture" Text="Live Capture" Grid.Row="8" Grid.Column="1" Clicked="liveCapture_Clicked"/> 
         <Grid x:Name="imageViewerContainer" Grid.Row="6" Grid.Column="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"> 
            <Grid.RowDefinitions> 
               <RowDefinition x:Name="row0" Height="*"/> 
            </Grid.RowDefinitions> 
            <Grid Margin="10,5" Grid.Row="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"> 
               <Grid.ColumnDefinitions> 
                  <ColumnDefinition Width="*"/> 
               </Grid.ColumnDefinitions> 
            </Grid> 
         </Grid> 
      </Grid> 
   </StackLayout> 
</ContentPage.Content> 

Right-click on the page and select View Code to bring up the code behind LiveCapturePage.xaml. Ensure the following statements are added to the using block at the top of LiveCapturePage.xaml.cs.

C#
using System; 
using Xamarin.Forms; 
using Xamarin.Forms.Xaml; 
using Leadtools; 
using Leadtools.Controls; 

Add an ImageViewer object as a global variable.

C#
private int frameCounter = 0; 
private ImageViewer _imageViewer; 
private RasterImage _image; 

Create a new method called InitImageViewer() and call it in the LiveCapturePage() method, as shown below.

C#
public LiveCapturePage() 
{ 
   InitializeComponent(); 
   InitImageViewer(); 
   leadCamera.CameraOptions.AutoRotateImage = true; 
} 

Create the Image Viewer

Add the code below to the new InitImageViewer() method.

C#
private void InitImageViewer() 
{ 
   // create the image viewer 
   _imageViewer = new ImageViewer 
   { 
      ViewHorizontalAlignment = ControlAlignment.Center, 
      ViewVerticalAlignment = ControlAlignment.Center, 
      BackgroundColor = Color.Black, 
      VerticalOptions = LayoutOptions.FillAndExpand, 
      HorizontalOptions = LayoutOptions.FillAndExpand, 
      Margin = new Thickness(0, 0), 
   }; 
 
   // Set the image to be zoomed out and fit the viewer 
   _imageViewer.Zoom(ControlSizeMode.FitAlways, 1, _imageViewer.DefaultZoomOrigin); 
 
   Grid.SetRow(_imageViewer, 0); 
   Grid.SetRowSpan(_imageViewer, 1); 
 
   // Apply pan zoom 
   ImageViewerPanZoomInteractiveMode panZoom = new ImageViewerPanZoomInteractiveMode(); 
   _imageViewer.InteractiveModes.Add(panZoom); 
 
   // Add the image viewer to the container created in the xaml file 
   imageViewerContainer.Children.Add(_imageViewer); 
} 

In the Solution Explorer, open AppDelegate.cs . Add the below line to the FinishedLaunching() method:

C#
Leadtools.Controls.iOS.Assembly.Use(); 

Add the Live Capture Code

In the LiveCapturePage.xaml.cs file, add the below code inside the LeadCamera_FrameReceived event handler. The newly added code will handle each frame and add it to the ImageViewer object.

C#
private void LeadCamera_FrameReceived(Leadtools.Camera.Xamarin.FrameHandlerEventArgs e) 
{ 
   RasterImage _image = e.Image.Clone(); 
   // Frame Received Handler Code  
   frameCounter = frameCounter + 1; 
   Device.BeginInvokeOnMainThread(() => 
   { 
      capturedFrames.Text = $"Frames Processed: {frameCounter}"; 
   }); 
 
   // Make sure to clone the image then auto dispose as the FrameReceived will be getting disposed 
   _imageViewer.AutoDisposeImages = false; 
   _imageViewer.Image = _image; 
   _imageViewer.AutoDisposeImages = true; 
} 

Run the Project

Select the desired project (iOS or Android) and run the project by pressing F5, or by selecting Debug -> Start Debugging.

If the steps were followed correctly, the application runs and it will ask to allow Camera permissions which is required. For testing, click the Live Capture button at the bottom of the device's screen. A preview from the device's camera will be displayed in the CameraView and the number of frames processed will increment for every frame processed. Click the Stop button to end the preview.

Screenshot of working application.

Wrap-up

This tutorial showed how to implement picture-in-picture mode using the CameraView class to process frames taken by the device's camera and display them in an ImageViewer.

See Also

Help Version 23.0.2024.4.23
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2024 LEAD Technologies, Inc. All Rights Reserved.


Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.