Get started with FacePing's face recognition API using .NET MAUI
Create a new .NET MAUI project:
dotnet new maui -n FacePingDemo
cd FacePingDemo
Create ViewModels/CreateGroupViewModel.cs
:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace FacePingDemo.ViewModels;
public partial class CreateGroupViewModel : ObservableObject
{
private readonly HttpClient _client;
private const string ApiKey = "your_api_key_here";
[ObservableProperty]
private string groupName;
[ObservableProperty]
private string status;
public CreateGroupViewModel()
{
_client = new HttpClient();
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
}
[RelayCommand]
private async Task CreateGroupAsync()
{
try
{
var response = await _client.PostAsync(
$"https://api.faceping.ai/groups/{GroupName}",
null);
if (response.IsSuccessStatusCode)
Status = "Group created successfully";
else
throw new Exception("Failed to create group");
}
catch (Exception ex)
{
Status = "Error creating group";
}
}
}
Create Views/CreateGroupPage.xaml
:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FacePingDemo.Views.CreateGroupPage">
<VerticalStackLayout Spacing="20" Padding="20">
<Entry Placeholder="Enter group name"
Text="{Binding GroupName}" />
<Button Text="Create Group"
Command="{Binding CreateGroupCommand}" />
<Label Text="{Binding Status}"
IsVisible="{Binding Status, Converter={StaticResource StringNotEmptyConverter}}" />
</VerticalStackLayout>
</ContentPage>
Create ViewModels/UploadFaceViewModel.cs
:
public partial class UploadFaceViewModel : ObservableObject
{
private readonly HttpClient _client;
private const string ApiKey = "your_api_key_here";
[ObservableProperty]
private ImageSource imageSource;
[ObservableProperty]
private string status;
public UploadFaceViewModel()
{
_client = new HttpClient();
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
}
[RelayCommand]
private async Task SelectImage()
{
var result = await MediaPicker.PickPhotoAsync();
if (result != null)
{
ImageSource = ImageSource.FromFile(result.FullPath);
await UploadImage(result);
}
}
private async Task UploadImage(FileResult image)
{
try
{
var content = new MultipartFormDataContent();
var stream = await image.OpenReadAsync();
content.Add(new StreamContent(stream), "image", image.FileName);
var response = await _client.PostAsync(
"https://api.faceping.ai/groups/my-group/faces",
content);
if (response.IsSuccessStatusCode)
Status = "Face uploaded successfully";
else
throw new Exception("Failed to upload face");
}
catch (Exception ex)
{
Status = "Error uploading face";
}
}
}
Create Views/UploadFacePage.xaml
:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FacePingDemo.Views.UploadFacePage">
<VerticalStackLayout Spacing="20" Padding="20">
<Button Text="Select Image"
Command="{Binding SelectImageCommand}" />
<Image Source="{Binding ImageSource}"
HeightRequest="200"
IsVisible="{Binding ImageSource, Converter={StaticResource NotNullConverter}}" />
<Label Text="{Binding Status}"
IsVisible="{Binding Status, Converter={StaticResource StringNotEmptyConverter}}" />
</VerticalStackLayout>
</ContentPage>
Create ViewModels/SearchFacesViewModel.cs
:
public partial class SearchFacesViewModel : ObservableObject
{
private readonly HttpClient _client;
private const string ApiKey = "your_api_key_here";
[ObservableProperty]
private ImageSource imageSource;
[ObservableProperty]
private string status;
[ObservableProperty]
private ObservableCollection<MatchResult> matches = new();
public SearchFacesViewModel()
{
_client = new HttpClient();
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
}
[RelayCommand]
private async Task SelectImage()
{
var result = await MediaPicker.PickPhotoAsync();
if (result != null)
{
ImageSource = ImageSource.FromFile(result.FullPath);
await SearchImage(result);
}
}
private async Task SearchImage(FileResult image)
{
try
{
var content = new MultipartFormDataContent();
var stream = await image.OpenReadAsync();
content.Add(new StreamContent(stream), "image", image.FileName);
var response = await _client.PostAsync(
"https://api.faceping.ai/groups/my-group/search",
content);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<SearchResult>();
Matches.Clear();
foreach (var match in result.Matches)
Matches.Add(match);
Status = $"Found {Matches.Count} matches";
}
else
throw new Exception("Failed to search faces");
}
catch (Exception ex)
{
Status = "Error searching faces";
Matches.Clear();
}
}
}
public class MatchResult
{
public double Score { get; set; }
}
public class SearchResult
{
public List<MatchResult> Matches { get; set; }
}
Create Views/SearchFacesPage.xaml
:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FacePingDemo.Views.SearchFacesPage">
<VerticalStackLayout Spacing="20" Padding="20">
<Button Text="Select Image"
Command="{Binding SelectImageCommand}" />
<Image Source="{Binding ImageSource}"
HeightRequest="200"
IsVisible="{Binding ImageSource, Converter={StaticResource NotNullConverter}}" />
<Label Text="{Binding Status}"
IsVisible="{Binding Status, Converter={StaticResource StringNotEmptyConverter}}" />
<CollectionView ItemsSource="{Binding Matches}"
IsVisible="{Binding Matches.Count, Converter={StaticResource NotZeroConverter}}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Score, StringFormat='Match Score: {0:F2}'}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>