This tutorial shows how to integrate picture-in-picture mode for video captured from the device's camera through the Xamarin Camera Control in a C# Xamarin application using the LEADTOOLS SDK.
Overview | |
---|---|
Summary | This tutorial covers how to integrate picture-in-picture to display live capture video frames in a C# Xamarin application. |
Completion Time | 30 minutes |
Visual Studio Project | Download tutorial project (510 KB) |
Platform | C# Xamarin Cross-Platform Application |
IDE | Visual Studio 2019, 2022 |
Development License | Download LEADTOOLS |
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 - Xamarin C#.
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:
Leadtools.Formats.Raster.Common
Leadtools.Viewer.Controls.Xamarin
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:
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
.
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Leadtools;
using Leadtools.Controls;
Add an ImageViewer object as a global variable.
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.
public LiveCapturePage()
{
InitializeComponent();
InitImageViewer();
leadCamera.CameraOptions.AutoRotateImage = true;
}
Add the code below to the new InitImageViewer()
method.
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:
Leadtools.Controls.iOS.Assembly.Use();
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.
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;
}
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.
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
.