Xamarin 相机控件与云:与 LEADTOOLS 的完美融合





0/5 (0投票)
使用 LEAD 的云服务,快速利用移动设备的摄像头,而无需了解原生相机 API。
引言
我们之前的产品展示重点介绍了如何使用 LEAD 新的 Xamarin 相机控件轻松利用移动设备摄像头。我们还将条形码 SDK 集成到应用程序中,以读取条形码并将找到的数据显示在设备的屏幕上。
继续Xamarin 相机控件的介绍,我们现在将把一个LEADTOOLS 云服务方法集成到我们的应用程序中,即 Merge(合并)方法。此方法将特定页面合并到另一个文件中,可以通过 POST 请求调用到以下 URL
[POST] https://azure.leadtools.com/api/Conversion/Merge
LEADTOOLS 云服务是 Web API 端点,客户无需自行设置服务器的麻烦即可访问 LEADTOOLS SDK 提供的高性能功能。我们目前提供文档转换、文档合并、红屏、条形码、OCR、MICR、AAMVAID 和名片提取服务。
我们在此应用程序中使用的 Merge 方法使用户能够选择要合并的输入文档中的哪些页面。您可以指定页面范围、页面数组或整个文档进行合并。如果目标格式是文档类型,则合并会保留文本,仅在需要时才使用 OCR。
应用 Xamarin 相机控件和 LEADTOOLS 云服务,为各行业的应用程序提供了无限的可能性。例如,假设一家保险公司需要财产损失的照片作为损失证明。与其发送 20 张单独的图片,不如创建一个包含这 20 张图片的单个文件。
设置您的应用
第一步是注册以获取免费的 30 天试用许可证:https://www.leadtools.com/downloads/nuget,然后注册以免费试用 LEADTOOLS 云服务:https://services.leadtools.com/account/register。
获得 LEADTOOLS 许可证后,打开 Visual Studio 2017 并创建一个新项目。首先,在 MainPage.xaml 中添加 Leadtools.Camera.Xamarin 程序集。
xmlns:leadtools="clr-namespace:Leadtools.Camera.Xamarin;assembly=Leadtools.Camera.Xamarin"
现在,将 `StackLayout` 中的默认自动生成标签替换为 Xamarin 的 `CameraView`,以及一个用于拍照的按钮和一个用于合并所有已拍摄图像的按钮。
<StackLayout>
<leadtools:CameraView x:Name="leadCamera" CameraOptions="Rear" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
<Button x:Name="snapBtn" HorizontalOptions="FillAndExpand" Text="Snap Picture" Clicked="SnapClicked" />
<Button x:Name="mergeBtn" HorizontalOptions="FillAndExpand" Text="Merge" Clicked="performMerge" />
<Button x:Name="downloadFileBtn" HorizontalOptions="FillAndExpand" Text="Go to file!" Clicked="downloadFile"/>
</StackLayout>
有关使用 LEADTOOLS Camera Control for Xamarin 的更多介绍以及设置 LEADTOOLS 许可证,请查看之前的文章:https://codeproject.org.cn/Articles/1349139/Finally-a-Camera-Control-for-Xamarin。请注意,在继续之前,必须完成上一篇文章。
现在已经添加了 Xamarin Camera Control 并设置了许可证,添加拍照的代码。`CameraView` 类有一个名为 `PictureReceived` 的事件,当调用 `ICamera.TakePicture()` 后捕获图像时,该事件将被触发。
对 `TakePicture` 方法的调用将放在按钮点击事件中。
void SnapClicked(object sender, EventArgs args)
{
snapBtn.IsEnabled = false;
leadCamera.Camera.TakePicture();
}
要创建 `PictureReceived` 的事件处理程序,请在 `InitializeComponent()` 之后添加以下代码行:
leadCamera.PictureReceived += LeadCamera_PictureReceived;
代码
首先,创建一些全局变量并创建一个新类。
private static HttpClient client;
private List<MergeRequestObject> MergeImages = new List<MergeRequestObject>();
private string hostedServicesUrl = "https://azure.leadtools.com/api/";
private static string fileUrl;
public class MergeRequestObject
{
public string FileId { get; set; }
}
如上所述,以及从我们之前的文章中,MainPage.xaml.cs 包含了启动 Xamarin Camera Control 所需的一切。此外,添加代码以自动旋转图像、启用合并按钮、禁用下载按钮,以及一个 `InitClient` 方法。您应该在 `InitializeComponent()` 下方看到以下内容。
leadCamera.CameraOptions.AutoRotateImage = true;
leadCamera.PictureReceived += LeadCamera_PictureReceived;
mergeBtn.IsEnabled = false;
downloadFileBtn.IsEnabled = false;
InitClient();
`InitClient` 用于将您的应用程序与 LEADTOOLS 云服务进行身份验证。
private void InitClient()
{
// Once you created your app in your account https://services.leadtools.com/manage
// you will receive an email with the AppId and Password
string AppId = "Enter AppID Here";
string Password = "Enter SecretKey Here";
client = new HttpClient
{
BaseAddress = new Uri(hostedServicesUrl)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string authData = string.Format("{0}:{1}", AppId, Password);
string authHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(authData));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authHeaderValue);
}
`PictureReceived` 中的代码将用于保存拍摄的每张图像,然后将其上传到 LEADTOOLS 云服务。在此示例中,图像将作为 PNG 存储在 `MemoryStream` 中。图像保存后,需要将其上传到 LEADTOOLS 云服务。为此,将使用一个名为 `UploadForMerge` 的方法。此方法需要内存流并返回一个 GUID。一旦您获得 GUID,它将被存储在一个列表中,`List<MergeRequestObject>` mergeImages。`MergeRequestObject` 是我们创建的一个类,其中包含一个名为 `FileID` 的字符串。`FileID` 现在将是 `UploadForMerge` 返回的 GUID。拍摄的每张图像都将经过此过程,并拥有自己的 GUID,该 GUID 将添加到列表中。
private void LeadCamera_PictureReceived(FrameHandlerEventArgs e)
{
Device.BeginInvokeOnMainThread(() =>
{
snapBtn.Text = "Image is uploading to LEADTOOLS Cloud Services, please wait";
mergeBtn.IsEnabled = false;
});
using (MemoryStream ms = new MemoryStream())
{
using (RasterCodecs codecs = new RasterCodecs())
{
codecs.Save(e.Image, ms, RasterImageFormat.Png, 0);
var id = UploadForMerge(ms);
MergeImages.Add(new MergeRequestObject { FileId = id.ToString() });
Device.BeginInvokeOnMainThread(() =>
{
snapBtn.IsEnabled = true;
snapBtn.Text = "Snap Picture";
mergeBtn.Text = $"Merge {MergeImages.Count} file(s)";
DisplayAlert("Image saved!", "Image has been uploaded", "OK");
mergeBtn.IsEnabled = true;
});
}
}
}
`UploadForMerge` 方法是将图像发送到 LEADTOOLS 云服务并返回 GUID 的地方。
public Guid UploadForMerge(MemoryStream uploadForMergeStream)
{
HttpContent byteContent = new ByteArrayContent(uploadForMergeStream.ToArray());
using (var formData = new MultipartFormDataContent())
{
formData.Add(byteContent, "imageStream");
var url = "UploadFile?forMerge=true";
var res = client.PostAsync(url, formData).Result;
var guid = Guid.Empty;
if (res.IsSuccessStatusCode)
{
var id = res.Content.ReadAsStringAsync().Result;
return Guid.Parse(id);
}
else
return Guid.Empty;
}
}
拍摄完所有照片并将其上传到 LEADTOOLS 云服务后,就可以将它们合并到一个文件中了。为此,创建一个名为 `PerformMerge` 的新方法。
void performMerge(object sender, EventArgs args)
{
Device.BeginInvokeOnMainThread(() =>
{
mergeBtn.Text = "Merging files, please wait";
snapBtn.IsEnabled = false;
mergeBtn.IsEnabled = false;
});
var id = PostMerge();
if (id == Guid.Empty)
Device.BeginInvokeOnMainThread(() =>
{
DisplayAlert("Error", "GUID is empty", "OK");
});
var results = Query(id.ToString());
// Parse results and add the URL to the fileUrl button
JArray array = JArray.Parse(results);
foreach (var requestReturn in array)
{
var UrlArray = JArray.Parse(requestReturn.SelectToken("urls").ToString());
foreach (var uri in UrlArray)
{
Device.BeginInvokeOnMainThread(() =>
{
fileUrl = uri.ToString();
});
}
}
// Clear list to create a new single file
MergeImages.Clear();
Device.BeginInvokeOnMainThread(() =>
{
downloadFileBtn.IsEnabled = true;
mergeBtn.Text = "File(s) have been merged";
snapBtn.IsEnabled = true;
});
}
`PerformMerge` 内部还有一个名为 `PostMerge` 的方法,该方法也将返回一个 GUID。
public Guid PostMerge()
{
var stringContent = new StringContent(JsonConvert.SerializeObject(MergeImages), Encoding.UTF8, "application/json");
// Format 4 will save merged files to a PDF
var url = $"Conversion/Merge?Format=4";
var res = client.PostAsync(url, stringContent).Result;
if (res.IsSuccessStatusCode)
{
var id = res.Content.ReadAsStringAsync().Result;
return Guid.Parse(id);
}
else
return Guid.Empty;
}
继续 `PerformMerge` 方法,这里将使用 `PostMerge` 返回的 ID 获取结果,然后使用一个接受字符串并返回结果的新方法 Query 进行查询。
private string Query(string id)
{
string queryUrl = $"Query?id={id.ToString()}";
int status = 100;
string results = "";
JObject returnedData = null;
while (status == 100 || status == 123)
{
Task.Delay(500).Wait();
var result = client.PostAsync(queryUrl, null).Result;
var returnedContent = result.Content.ReadAsStringAsync().Result;
returnedData = JObject.Parse(returnedContent);
status = (int)returnedData.SelectToken("FileStatus");
}
if (status == 200)
results = returnedData.SelectToken("RequestData").ToString();
return results;
}
添加 `downloadFile` 方法以下载文件。
void downloadFile(object sender, EventArgs args)
{
Device.OpenUri(new Uri(fileUrl));
}
结论
这两项技术为开发人员提供了:一、访问移动设备摄像机的高级 API;二、对程序员友好的 Web API。两者的结合使开发人员能够创建即时移动服务应用程序。
创建账户并免费获取您的前 50 页!
https://services.leadtools.com/account/register
支持
需要帮助来启动这个示例吗?联系我们的支持团队以获得免费技术支持!有关定价或许可问题,您可以联系我们的销售团队(sales@leadtools.com)或致电 704-332-5532。