介绍
我们之前的产品展示了如何使用LEAD的新Xamarin Camera Control轻松利用移动设备相机。我们还将条形码SDK合并到应用程序中以读取条形码并显示找到设备屏幕的数据。
继续使用Xamarin Camera Control系列,我们现在将采用新的LEADTOOLS云服务方法之一纳入我们的应用程序Merge方法。此方法将特定页面合并到另一个文件中,并且可以使用对以下URL的POST请求进行调用:
[POST] https://azure.leadtools.com/api/Conversion/Merge
LEADTOOLS云服务是Web API端点,客户可以访问LEADTOOLS SDK提供的高性能功能,而无需设置自己的服务器。我们目前提供文档转换,文档合并,编辑,条形码,OCR,MICR,AAMVAID和名片提取服务。
我们为此应用程序使用的Merge方法使用户能够选择要合并的输入文档中的哪些页面。指定页面范围,页面数组或要合并的整个文档。如果目标格式是文档类型,则merge将保留文本,并在需要时仅使用OCR。
同时应用Xamarin Camera Control和LEADTOOLS云服务,可以为各行各业的应用提供无限的潜力。例如,保险公司要求提供损坏财产的照片以证明损害赔偿。您可以创建一个包含这20个图像的文件,而不是发送20个单独的图像。
设置您的应用程序
第一步是通过在https://www.leadtools.com/downloads/nuget注册获取免费的30天评估许可证,并在https://services.leadtools上为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://www.codeproject.com/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云服务。在此示例中,图像将MemoryStream
作为PNG 存储在a 中。保存图像后,需要将其上传到LEADTOOLS云服务。为此,UploadForMerge
将使用一个名为的方法。此方法将需要内存流并将返回GUID。获得GUID后,它将存储在一个列表List<MergeRequestObject>
mergeImages中。这MergeRequestObject
是我们创建的一个包含一个名为的字符串的类FileID
。FileID
现在将是从返回的GUID UploadForMerge
。拍摄的每张图像都将经历此过程,并且将具有自己的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;
});
}
Inside PerformMerge
是另一个名为PostMerge
method的方法,它也会返回一个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
方法,这将是使用返回的ID返回的结果PostMerge
,然后使用名为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。通过组合这些,开发人员可以随时随地创建移动服务应用程序。