将Azure计算机视觉添加到Xamarin应用程序简单体验
微软Azure提供了大量的AI及机器学习功能,可以通过简单的RestAPI调用。
关于此文中提到的Azure计算机视觉,可查看此链接的详细介绍。
通过微软的服务,只需要几行代码即可使用计算机视觉中的 REST API 分析图像提取特征信息。
开发环境说明及初始准备。
开发工具:Visual Studio For Mac 2019 preview
创建Xamarin.Forms程序,PCL类库逐渐在过时,所以新项目的共享代码选择.NET Standard。

1.在共享项目中添加Xam.Plugin.Media的NuGet包引用,此包可以大大减少访问相册的代码量。
PS:Xamarin.Essentials还没有提供摄像头和相册的调用功能。
NuGet包安装完成后,会显示readme.txt,增加对应的访问权限设定,在此NuGet包的GitHub中同样有详细说明,
地址为:https://github.com/jamesmontemagno/MediaPlugin
2.添加对Microsoft.Azure.CognitiveServices.Vision.ComputerVision的Nuget包引用。
此包提供了Azure计算机视觉的API访问。
3.注册计算机视觉的API Key。
点击 链接

点击免费试用认知服务,登陆微软账号,
点击获取API Key,Azure会提供一个7天的免费试用Key

初始准备完成。
程序代码编写
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:RevealTest" x:Class="RevealTest.MainPage" xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" ios:Page.UseSafeArea="true">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height=".2*" />
<RowDefinition Height="3*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.Column="0" x:Name="imgSelected" Aspect="AspectFit" />
<Button x:Name="btnPick" Text="选择图片" Clicked="Handle_Clicked" Grid.Row="1" Grid.Column="0" />
<TableView Grid.Row="2" Grid.Column="0" x:Name="TableView">
<TableRoot>
<TableSection Title="图片信息" x:Name="TableSection">
</TableSection>
</TableRoot>
</TableView>
</Grid>
</ContentPage.Content>
</ContentPage>
PS:此行代码代表对刘海屏进行适配。
ios:Page.UseSafeArea="true"
public partial class MainPage : ContentPage
{
public string subscriptionKey = "申请的API Key";
public MainPage()
{
InitializeComponent();
}
async void Handle_Clicked(object sender, System.EventArgs e)
{
TableView.Root.Clear();
TableRoot root = new TableRoot();
await CrossMedia.Current.Initialize();
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Photos);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Photos))
{
await DisplayAlert("提示", "需要访问您的相册", "OK");
}
await DisplayAlert("提示", "需要访问您的相册", "OK");
if (Device.RuntimePlatform == Device.iOS)
{
Device.OpenUri(new Uri("app-settings:"));
}
return;
}
try
{
var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium
});
if (file == null) return;
imgSelected.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
return stream;
});
var result = await MakeAnalysisRequest(file.Path);
if (result == null)
{
TableSection.Add(CreateTextCell("空", "空"));
}
if (result.Metadata != null)
{
TableSection.Add(CreateTextCell("图片格式", result.Metadata.Format + " " + result.Metadata.Width.ToString() + "*" + result.Metadata.Height));
}
if (result.Description != null)
{
foreach (var item in result.Description.Captions)
{
TableSection.Add(CreateTextCell("图片内容推测:" + item.Text, "可能性" + item.Confidence));
}
string tagdesc = "";
foreach (var item in result.Description.Tags)
{
tagdesc += item + ", ";
}
TableSection.Add(CreateTextCell("图片标签", tagdesc));
}
if (result.Tags != null)
{
foreach (var item in result.Tags)
{
TableSection.Add(CreateTextCell(item.Name, "可能性" + item.Confidence));
}
}
TableView.Root.Add(TableSection);
}
catch (Exception ex)
{
string test = ex.Message;
}
}
private TextCell CreateTextCell(string text, string detail)
{
return new TextCell
{
Text = text,
Detail = detail,
DetailColor = Color.Gray
};
}
public async Task<ImageAnalysis> MakeAnalysisRequest(string imageFilePath)
{
using (var fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
{
var apikey = new ApiKeyServiceClientCredentials(subscriptionKey);
var visualFeatures = new List<VisualFeatureTypes>
{
(VisualFeatureTypes)Enum.Parse(typeof(VisualFeatureTypes), "Categories"),
(VisualFeatureTypes)Enum.Parse(typeof(VisualFeatureTypes), "Tags"),
(VisualFeatureTypes)Enum.Parse(typeof(VisualFeatureTypes), "ImageType"),
(VisualFeatureTypes)Enum.Parse(typeof(VisualFeatureTypes), "Color"),
(VisualFeatureTypes)Enum.Parse(typeof(VisualFeatureTypes), "Faces"),
(VisualFeatureTypes)Enum.Parse(typeof(VisualFeatureTypes), "Adult"),
(VisualFeatureTypes)Enum.Parse(typeof(VisualFeatureTypes), "Description")
};
using (var client = new ComputerVisionClient(apikey) { Endpoint = "https://westcentralus.api.cognitive.microsoft.com" })
{
ImageAnalysis analysisResult = await client.AnalyzeImageInStreamAsync(fileStream, visualFeatures.ToArray(), null, "zh");
return analysisResult;
}
}
}
}
由于只是体验性质,就没有使用MVVM模式,并且结果展示也没有使用特别恰当的方式。
执行效果

将Azure计算机视觉添加到Xamarin应用程序简单体验的更多相关文章
- 在 Windows Azure 上设计多租户应用程序
作者:Suren Machiraju 和 Ralph Squillace 审校:Christian Martinez.James Podgorski.Valery Mizonov 和 Michael ...
- 使用Azure DevOps Pipeline实现.Net Core程序的CD
上一次我们讲了使用Azure DevOps Pipeline实现.Net Core程序的CI.这次我们来演示下如何使用Azure DevOps实现.Net Core程序的CD. 实现本次目标我们除了A ...
- Linux systemd 打开调试终端、添加开机自运行程序
/************************************************************************* * Linux systemd 打开调试终端.添加 ...
- 【Xamarin挖墙脚系列:如何从一个Apk程序转化为Xamarin的程序】
原文:[Xamarin挖墙脚系列:如何从一个Apk程序转化为Xamarin的程序] 工欲善其事必先利其器:工具下载:http://pan.baidu.com/s/1skxjwgH 接下来,我用个小的应 ...
- 从零开始学Xamarin.Forms(四) Android 准备步骤(添加第三方Xamarin.Forms.Labs库)
原文:从零开始学Xamarin.Forms(四) Android 准备步骤(添加第三方Xamarin.Forms.Labs库) 1.安装对应dll Update-Package Xama ...
- 故障排除:无法启动、访问或连接到 Azure 虚拟机上运行的应用程序
有多种原因可导致无法启用或连接到在 Azure 虚拟机 (VM) 上运行的应用程序.原因包括应用程序未在预期端口上运行或侦听.侦听端口受到阻止,或网络规则未将流量正确传递到应用程序.本文说明有条理地找 ...
- wxWidgets初学者导引(3)——wxWidgets应用程序初体验
wxWidgets初学者导引全目录 PDF版及附件下载 1 前言2 下载.安装wxWidgets3 wxWidgets应用程序初体验4 wxWidgets学习资料及利用方法指导5 用wxSmith ...
- 微信小程序简单封装图片上传组件
微信小程序简单封装图片上传组件 希望自己 "day day up" -----小陶 我从哪里来 在写小程序的时候需要上传图片,个人觉得官方提供的 Uploader 组件不是太好用, ...
- C#基础--.net平台的重要组成部分以及.net程序简单的编译原理
.net平台的组成只要有两部分 FCL:框架类库 CLR:公共语言运行时 .net程序简单的编译原理 1.0:使用C#编译器(csc.exe) 将C#源代码编译成程序集+{编译之前:会检查C ...
随机推荐
- Maximum Average Subarray I LT643
Given an array consisting of n integers, find the contiguous subarray of given length k that has the ...
- 提升HTML5的性能体验系列之三 流畅下拉刷新和上拉
下拉刷新 为实现下拉刷新功能,大多H5框架都是通过DIV模拟下拉回弹动画,在低端android手机(Android4.4以下)上,DIV动画经常出现卡顿现象(特别是图文列表的情况).解决方案还是web ...
- PSP(3.30——4.5)以及周记录
1.PSP 3.30 12:00 13:00 10 50 Account前端 A Y min 13:00 13:20 0 20 站立会议 A Y min 15:15 17:00 20 85 Accou ...
- java学习第六周
这是暑假学习的第六周,在这周我练习了老师给的例题,还是有一些地方看不懂,这周我对那些不懂的地方用看视频来进行解答,以及进行第二次复习. 下周我会对Java进行更加详细的复习,做好笔记,在LeetCod ...
- 2018.10.30 NOIP模拟 有环无向图(dijkstra+巧妙建图)
传送门 建图巧妙啊. 对于每个点的出边,我们将它们排序之后依次连边. 这样可以把O(m2)O(m^2)O(m2)的边数变成O(m)O(m)O(m)的了. 连的权值就是max(edgemax(edgem ...
- 在 Linux/windows下 命令行中使用和执行 PHP 代码[交互式php]
[注释]在ubuntu下,升级php到7.1版本,虽然提示的是Interactive mode enabled, 但实际上可以直接书写命令,和interactive shell效果一样. 一:wind ...
- Java,数据库中的数据导入到Excel
private static void executeMethod(JobExecutionContext arg0) throws Exception{ try { TContrastService ...
- s5-15 开放的最短路径优先_OSPF
L-S路由协议的实例—OSPF 开放的路径优先(Open Shortest Path First) 使用图(graph)来表述真实的网络 - 每个路由器/Lan都是一个节点 - 测量代价/量度(met ...
- 实战fortran77基础语法2
由于大量的接触fortran77,先学习fortran77吧 1.fortran不区分大小写,fortran77一般全部大写,感觉没必要,不好读,还是用大小写混合着写吧.后缀 .for 为固定格式的代 ...
- 不同数据源之间的数据同步jdbc解决方案
最近项目中用到的数据要从一个数据源获取存进另一个数据源,简单的jdbc解决方案. package com.sh.ideal.test.syns; import java.sql.Connection; ...