给你的应用“一只”智慧的眼睛 —— Barcode常识普及以及识别信息处理
在“如何用MediaCapture解决二维码扫描问题”这篇文章中,我们通过“成像”、“截图”与“识别”三个步骤介绍了使用MediaCapture扫码的主要过程及注意事项。本文主要针对“识别”的过程,对Barcode的概念作出一个较为简单的介绍,同时也会讨论ZXing的使用方法。
ZXing是一个Java实现的开源库,可以支持多种Barcode的识别和生成,同时也为其它的语言提供了相应的接口,比如C++、Python、.Net等等。这里,我们使用ZXing.Net,可以很方便的集成在UWP环境中,便于扫码工作的开发。
Barcode简介
Barcode是一种机器可读的数据表示方式,作为某种商品或产品的唯一标识。通常被翻译成条码,但我个人并不喜欢这种翻译,因为不是所有的barcode都是条形的。当然,这应该是有历史原因的。Barcode的形式多种多样,按照它们的外观,可以分为Linear barcode(一维码)和Matrix barcode(二维码)。你可能认为你对它们都有所了解,因为它们大概都是这个样子的:
但事实上,它们有甚至有可能是这样子的:
我们通常所说的二维码和上文提到的二维码有所不同,只是Matrix barcode的一种,叫做QR code。举这些例子只是为了说明Barcode种类繁多,有些编码格式并不常用,即使是ZXing也没有做到所有格式的支持,开发者只需了解就好。
Code 39、Code 128、EAN、UPC、QR Code是我们生活中能经常见到的几种编码格式,同时ZXing对几种格式都有比较好的支持。其中,UPC-A是一种国际通用的编码格式,由12个数字构成,EAN-13是在UPC-A基础上的一种扩充(多了一个数字)。快数一数你身边的薯片的编码是不是13位!如果是的话,它最前边的两个数字是不是“69”?在EAN-13的编码体系中,前三位数字表示商品生产商的国家(并不是商品所属公司的国家),中国的编码是690~699,美国是(000~019、030~039、060~139),日本是(450~459、490~499),and so on。不同的编码格式通常用在不同的领域,如果你看到了一个Code 39或者Code 128的Barcode,那么这很就可能是一个快递编码,这个时候你就可以去那些提供快递查询的网站查询一下你的快递信息,如果有API提供出来那就更是再好不过了。至于QR Code,就是我们经常用手机扫一扫的二维码,表示的信息更是多种多样,并不仅仅是一个url那么简单,至于这些信息如何处理,是我们一会儿将要讨论的内容。
配置工程
在另一篇文章中提到,可以在Visual Studio环境下,通过nuget管理器安装ZXing.Net,如果你仅仅希望通过扫码得到一个扫码结果(比如字符串,或者是一个链接),当然可以这样做,而且过程十分简单。但这里我们并不推荐这种方法,因为从NuGet上得到的package只提供了一些简单的API接口,并没有将ZXing.Net的API全部提供出来,至于为什么这么做,说实话,我也不知道,可能是为了稳定性等原因。如果你是一个比较执着的programmer,也可以在使用NuGet包的情况下,自己实现其它丰富的功能,毕竟有ZXing的源代码可以参考,这就是开源的好处!在这篇文章中,我们还是以简单为主,毕竟ZXing.Net已经为我们提供了编译好的动态连接库,有什么理由让我们不用呢?
Important 官网提供的库和NuGet提供的库API稍微有些不同,如果需要更换,需要稍作修改,但过程并不是很繁琐。
你可以从http://zxingnet.codeplex.com/下载ZXing.Net的Release,压缩包目录下的/winrt/zxing.winrt.dll即是我们希望添加到工程的引用。
然后,把这个reference添加到相应的工程里就行:
获取Barcode内容信息
首先,你可以按照“如何用MediaCapture解决二维码扫描问题”这篇文章中提供的步骤,初始化摄像头、设置Timer并添加Tick事件,在Tick事件中,通过调用ZXing.Net的API获取扫码结果。
private async void TimerTick(object sender, object e)
{
try
{
if (_mediaCapture == null)
return;
var props = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview);
uint width = , height = ;
if (props is ImageEncodingProperties)
{
width = (props as ImageEncodingProperties).Width;
height = (props as ImageEncodingProperties).Height;
}
else if (props is VideoEncodingProperties)
{
width = (props as VideoEncodingProperties).Width;
height = (props as VideoEncodingProperties).Height;
}
System.Diagnostics.Debug.WriteLine("Start scanning..."); Result decodeResult = null;
using (VideoFrame frameFormat = new VideoFrame(BitmapPixelFormat.Rgba8, (int)width, (int)height))
{
using (var frame = await _mediaCapture.GetPreviewFrameAsync(frameFormat))
{
var buffer = new Windows.Storage.Streams.Buffer(
(uint)( * frame.SoftwareBitmap.PixelWidth * frame.SoftwareBitmap.PixelHeight));
frame.SoftwareBitmap.CopyToBuffer(buffer);
var reader = new BarcodeReader();
decodeResult = reader.Decode(buffer.ToArray(), (int)width, (int)height, RGBLuminanceSource.BitmapFormat.RGB32);
System.Diagnostics.Debug.WriteLine(decodeResult);
if (decodeResult != null)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
resultTextBlock.Text = decodeResult.Text;
});
}
}
}
//You can handle decodeResult by other ways.
if (decodeResult != null)
await Windows.System.Launcher.LaunchUriAsync(new Uri(decodeResult.Text));
}
catch (ArgumentNullException ane)
{
System.Diagnostics.Debug.WriteLine(ane.ToString());
}
catch (UriFormatException ufe)
{
System.Diagnostics.Debug.WriteLine(ufe.ToString());
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Timer tick exception: {0}!", ex);
}
}
得到的Result包含两个重要的属性: Text和BarcodeFormat。其中,Text就是相关Barcode表示的文本信息,而BarcodeFormat则是对应的编码方式。你可能会问,知道内容就好了,要编码方式有什么用?这里有个问题是,同样的一段文本信息(尤其是纯数字信息)在不同的编码方式下可能会有不同的含义(比如两种完全不同的商品)。
解析内容
如同前面所说,Barcode可以表示各种各样的信息,可能是“Hello UWP!”这样的纯文本,也可能是图书的ISBN编码,或者是一个网络上的URL连接。这里,我们可以通过编码类型来判断,因为不同的编码类型应用场景不一样嘛,许多一维码根本就不支持非数字文本。此外,ZXing也为我们提供的方便的接口(NuGet上的ZXing.Net并没有),能标识出文本的具体内容:
ParsedResult parsedResult = ResultParser.parseResult(result);
parsedResult包含以下几种信息:
//
// Summary:
// Represents the type of data encoded by a barcode -- from plain text, to a URI,
// to an e-mail address, etc.
public enum ParsedResultType
{
ADDRESSBOOK = ,
EMAIL_ADDRESS = ,
PRODUCT = ,
URI = ,
TEXT = ,
GEO = ,
TEL = ,
SMS = ,
CALENDAR = ,
WIFI = ,
ISBN = ,
VIN =
}
ParsedResultType
后续工作
有了以上的内容,我们就可以对信息作进一步的处理,这就需要依赖于第三方服务提供的API接口了。
快递:
“快递100”为用户提供了一个非常方便的页面,通过快递条码就可以轻松查询到快递信息。
http://m.kuaidi100.com/result.jsp?nu={0}
如果想要自定义页面,则推荐使用其API: http://www.kuaidi100.com/openapi/
商品:
亚马逊为其网站的商品提供了商品搜索的API,通过提供条码Id及其类型,则可以查询到相应商品信息。
在ItemLookup页面中,填写一些查询的基本信息,Marketplace可供用户选择查询的数据源,webservices.amazon.com为美国的市场,中国市场可以选择webservices.amazon.cn。下面的三个参数需要用户注册亚马逊的AWS服务(注册过程相当复杂╮(╯_╰)╭)。
在ItemLookup的过程,设置ItemId(code信息)和IdType(这里可以选择ASIN、SKU、UPC、EAN、ISBN),然后点击Run request就可以生成Request请求的URL,并且能获取到响应的服务器Response——一个xml文档,包含商品的各种信息。
Signed Request URL:
http://webservices.amazon.com/onca/xml?AWSAccessKeyId=********************&AssociateTag=************&IdType=UPC&ItemId=431604028525&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers&SearchIndex=All&Service=AWSECommerceService&Timestamp=2016-05-30T12%3A49%3A51.000Z&Signature=**********************************************
Response:
<?xml version="1.0" ?>
<ItemLookupResponse
xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
<OperationRequest>
<HTTPHeaders>
<Header Name="UserAgent" Value="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586"></Header>
</HTTPHeaders>
<RequestId>f90faa33-3fb2-4fd7-a885-abe33ea6967f</RequestId>
<Arguments>
<Argument Name="AWSAccessKeyId" Value="AKIAIZNMTNCCU6OFZG4A"></Argument>
<Argument Name="AssociateTag" Value="************"></Argument>
<Argument Name="IdType" Value="UPC"></Argument>
<Argument Name="ItemId" Value="431604028525"></Argument>
<Argument Name="Operation" Value="ItemLookup"></Argument>
<Argument Name="ResponseGroup" Value="Images,ItemAttributes,Offers"></Argument>
<Argument Name="SearchIndex" Value="All"></Argument>
<Argument Name="Service" Value="AWSECommerceService"></Argument>
<Argument Name="Timestamp" Value="2016-05-30T12:49:51.000Z"></Argument>
<Argument Name="Signature" Value="********************************************"></Argument>
</Arguments>
<RequestProcessingTime>0.1724468780000000</RequestProcessingTime>
</OperationRequest>
<Items>
<Request>
<IsValid>True</IsValid>
<ItemLookupRequest>
<IdType>UPC</IdType>
<ItemId>431604028525</ItemId>
<ResponseGroup>Images</ResponseGroup>
<ResponseGroup>ItemAttributes</ResponseGroup>
<ResponseGroup>Offers</ResponseGroup>
<SearchIndex>All</SearchIndex>
<VariationPage>All</VariationPage>
</ItemLookupRequest>
</Request>
<Item>
<ASIN>B008BO4D9G</ASIN>
<DetailPageURL>http://www.amazon.com/Nature-Made-Pharmacist-Recommended-Concentrate/dp/B008BO4D9G%3FSubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB008BO4D9G</DetailPageURL>
<ItemLinks>
<ItemLink>
<Description>Technical Details</Description>
<URL>http://www.amazon.com/Nature-Made-Pharmacist-Recommended-Concentrate/dp/tech-data/B008BO4D9G%3FSubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</URL>
</ItemLink>
<ItemLink>
<Description>Add To Baby Registry</Description>
<URL>http://www.amazon.com/gp/registry/baby/add-item.html%3Fasin.0%3DB008BO4D9G%26SubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</URL>
</ItemLink>
<ItemLink>
<Description>Add To Wedding Registry</Description>
<URL>http://www.amazon.com/gp/registry/wedding/add-item.html%3Fasin.0%3DB008BO4D9G%26SubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</URL>
</ItemLink>
<ItemLink>
<Description>Add To Wishlist</Description>
<URL>http://www.amazon.com/gp/registry/wishlist/add-item.html%3Fasin.0%3DB008BO4D9G%26SubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</URL>
</ItemLink>
<ItemLink>
<Description>Tell A Friend</Description>
<URL>http://www.amazon.com/gp/pdp/taf/B008BO4D9G%3FSubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</URL>
</ItemLink>
<ItemLink>
<Description>All Customer Reviews</Description>
<URL>http://www.amazon.com/review/product/B008BO4D9G%3FSubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</URL>
</ItemLink>
<ItemLink>
<Description>All Offers</Description>
<URL>http://www.amazon.com/gp/offer-listing/B008BO4D9G%3FSubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</URL>
</ItemLink>
</ItemLinks>
<ImageSets>
<ImageSet Category="swatch">
<SwatchImage>
<URL>http://ecx.images-amazon.com/images/I/51j%2BGzAmXTL._SL30_.jpg</URL>
<Height Units="pixels">30</Height>
<Width Units="pixels">15</Width>
</SwatchImage>
<SmallImage>
<URL>http://ecx.images-amazon.com/images/I/51j%2BGzAmXTL._SL75_.jpg</URL>
<Height Units="pixels">75</Height>
<Width Units="pixels">37</Width>
</SmallImage>
<ThumbnailImage>
<URL>http://ecx.images-amazon.com/images/I/51j%2BGzAmXTL._SL75_.jpg</URL>
<Height Units="pixels">75</Height>
<Width Units="pixels">37</Width>
</ThumbnailImage>
<TinyImage>
<URL>http://ecx.images-amazon.com/images/I/51j%2BGzAmXTL._SL110_.jpg</URL>
<Height Units="pixels">110</Height>
<Width Units="pixels">54</Width>
</TinyImage>
<MediumImage>
<URL>http://ecx.images-amazon.com/images/I/51j%2BGzAmXTL._SL160_.jpg</URL>
<Height Units="pixels">160</Height>
<Width Units="pixels">79</Width>
</MediumImage>
<LargeImage>
<URL>http://ecx.images-amazon.com/images/I/51j%2BGzAmXTL.jpg</URL>
<Height Units="pixels">500</Height>
<Width Units="pixels">247</Width>
</LargeImage>
</ImageSet>
<ImageSet Category="variant">
<SwatchImage>
<URL>http://ecx.images-amazon.com/images/I/51C8Vnbv71L._SL30_.jpg</URL>
<Height Units="pixels">30</Height>
<Width Units="pixels">19</Width>
</SwatchImage>
<SmallImage>
<URL>http://ecx.images-amazon.com/images/I/51C8Vnbv71L._SL75_.jpg</URL>
<Height Units="pixels">75</Height>
<Width Units="pixels">48</Width>
</SmallImage>
<ThumbnailImage>
<URL>http://ecx.images-amazon.com/images/I/51C8Vnbv71L._SL75_.jpg</URL>
<Height Units="pixels">75</Height>
<Width Units="pixels">48</Width>
</ThumbnailImage>
<TinyImage>
<URL>http://ecx.images-amazon.com/images/I/51C8Vnbv71L._SL110_.jpg</URL>
<Height Units="pixels">110</Height>
<Width Units="pixels">71</Width>
</TinyImage>
<MediumImage>
<URL>http://ecx.images-amazon.com/images/I/51C8Vnbv71L._SL160_.jpg</URL>
<Height Units="pixels">160</Height>
<Width Units="pixels">103</Width>
</MediumImage>
<LargeImage>
<URL>http://ecx.images-amazon.com/images/I/51C8Vnbv71L.jpg</URL>
<Height Units="pixels">500</Height>
<Width Units="pixels">321</Width>
</LargeImage>
</ImageSet>
<ImageSet Category="variant">
<SwatchImage>
<URL>http://ecx.images-amazon.com/images/I/31m-odZf5HL._SL30_.jpg</URL>
<Height Units="pixels">30</Height>
<Width Units="pixels">22</Width>
</SwatchImage>
<SmallImage>
<URL>http://ecx.images-amazon.com/images/I/31m-odZf5HL._SL75_.jpg</URL>
<Height Units="pixels">75</Height>
<Width Units="pixels">56</Width>
</SmallImage>
<ThumbnailImage>
<URL>http://ecx.images-amazon.com/images/I/31m-odZf5HL._SL75_.jpg</URL>
<Height Units="pixels">75</Height>
<Width Units="pixels">56</Width>
</ThumbnailImage>
<TinyImage>
<URL>http://ecx.images-amazon.com/images/I/31m-odZf5HL._SL110_.jpg</URL>
<Height Units="pixels">110</Height>
<Width Units="pixels">82</Width>
</TinyImage>
<MediumImage>
<URL>http://ecx.images-amazon.com/images/I/31m-odZf5HL._SL160_.jpg</URL>
<Height Units="pixels">160</Height>
<Width Units="pixels">120</Width>
</MediumImage>
<LargeImage>
<URL>http://ecx.images-amazon.com/images/I/31m-odZf5HL.jpg</URL>
<Height Units="pixels">500</Height>
<Width Units="pixels">375</Width>
</LargeImage>
</ImageSet>
</ImageSets>
<ItemAttributes>
<Binding>Health and Beauty</Binding>
<Brand>Nature Made</Brand>
<CatalogNumberList>
<CatalogNumberListElement>474911</CatalogNumberListElement>
</CatalogNumberList>
<EAN>0031604028527</EAN>
<EANList>
<EANListElement>0031604028527</EANListElement>
<EANListElement>0783318987897</EANListElement>
<EANListElement>0431604028525</EANListElement>
</EANList>
<Feature>USP VERIFIED - United States Pharmacopeia (USP) sets standards for medicines, food ingredients, and dietary supplements worldwide. Nature Made was the first supplement product to be verified by USP, including fish oil supplements.</Feature>
<Feature>FOOD EQUIVALENT - Two fish oil pills contain the same amount of omega-3 fatty acids of two servings of fish.</Feature>
<Feature>SOURCE AND PURITY - Comes from deep ocean water fish (NOT FARM RAISED) and state-of-the-art purification processes remove mercury. Omega-3 fish oil helps support a healthy heart.</Feature>
<Feature>2 BOTTLES OF 200 GEL TABS EACH -There are 200 fish oil capsules in each of two bottles, for a total of 400 softgels.</Feature>
<Feature>HIGH QUANTITY DOSAGE - Nature Made Fish Oil daily suggested usage contains 2,400 mg of fish oil with 720 mg of Omega-3 Fatty Acids (including 360 mg EPA and 240 mg DHA).</Feature>
<IsAdultProduct>0</IsAdultProduct>
<ItemDimensions>
<Height Units="hundredths-inches">313</Height>
<Length Units="hundredths-inches">613</Length>
<Weight Units="hundredths-pounds">174</Weight>
<Width Units="hundredths-inches">625</Width>
</ItemDimensions>
<Label>Nature Made</Label>
<Manufacturer>Nature Made</Manufacturer>
<MPN>474911</MPN>
<NumberOfItems>1</NumberOfItems>
<PackageDimensions>
<Height Units="hundredths-inches">320</Height>
<Length Units="hundredths-inches">630</Length>
<Weight Units="hundredths-pounds">180</Weight>
<Width Units="hundredths-inches">620</Width>
</PackageDimensions>
<PackageQuantity>1</PackageQuantity>
<PartNumber>474911</PartNumber>
<ProductGroup>Health and Beauty</ProductGroup>
<ProductTypeName>HEALTH_PERSONAL_CARE</ProductTypeName>
<Publisher>Nature Made</Publisher>
<Size>400 Softgels</Size>
<Studio>Nature Made</Studio>
<Title>Nature Made Fish Oil (400 Softgels) Pharmacist Recommended Fish Oil Pills (2400mg Fish Oil Concentrate, 720mg of Omega 3 Fatty Acids, 360mg EPA, 240 mg DHA)</Title>
<UPC>431604028525</UPC>
<UPCList>
<UPCListElement>431604028525</UPCListElement>
<UPCListElement>783318987897</UPCListElement>
<UPCListElement>031604028527</UPCListElement>
</UPCList>
</ItemAttributes>
<OfferSummary>
<LowestNewPrice>
<Amount>1560</Amount>
<CurrencyCode>USD</CurrencyCode>
<FormattedPrice>$15.60</FormattedPrice>
</LowestNewPrice>
<TotalNew>64</TotalNew>
<TotalUsed>0</TotalUsed>
<TotalCollectible>0</TotalCollectible>
<TotalRefurbished>0</TotalRefurbished>
</OfferSummary>
<Offers>
<TotalOffers>1</TotalOffers>
<TotalOfferPages>1</TotalOfferPages>
<MoreOffersUrl>http://www.amazon.com/gp/offer-listing/B008BO4D9G%3FSubscriptionId%3DAKIAIZNMTNCCU6OFZG4A%26tag%3Dfreshomer-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB008BO4D9G</MoreOffersUrl>
<Offer>
<OfferAttributes>
<Condition>New</Condition>
</OfferAttributes>
<OfferListing>
<OfferListingId>lt2bT68NjTRG7AuG%2FAAqcBmiJtLextibUqq62er5gQHN%2FtsGphHchT6YZGwo9DRl4CDw8UuCEQki2TAilIIVkKZ03DwP194gQLXxDlAXT%2BvPLPifatvCMnSk9skoDe%2FETTBJg3o7sdO%2B%2FevV0UWM6Q%3D%3D</OfferListingId>
<Price>
<Amount>2135</Amount>
<CurrencyCode>USD</CurrencyCode>
<FormattedPrice>$21.35</FormattedPrice>
</Price>
<Availability>Usually ships in 24 hours</Availability>
<AvailabilityAttributes>
<AvailabilityType>now</AvailabilityType>
<MinimumHours>0</MinimumHours>
<MaximumHours>0</MaximumHours>
</AvailabilityAttributes>
<IsEligibleForSuperSaverShipping>0</IsEligibleForSuperSaverShipping>
<IsEligibleForPrime>1</IsEligibleForPrime>
</OfferListing>
</Offer>
</Offers>
</Item>
</Items>
</ItemLookupResponse>
Response
当然,这只是Amazon为我们提供的一个开发工具,在真正开发过程中,需要用code来构造Amazon的数据请求。
一些数据常量:
private const string AWS_ACCESS_KEY_ID = "********************";
private const string AWS_SECRET_KEY = "****************************************";
private const string AWS_ASSOCIATE_TAG = "************";
private const string FORMAT_SORTABLE_TIME = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.000Z'"; private static readonly string HASH_ALGORITHM_NAME = MacAlgorithmNames.HmacSha256; private const string ENDPOINT_ITEM_SEARCH_BY_PRODUCT_ID =
"http://webservices.amazon.com/onca/xml?AWSAccessKeyId={0}&AssociateTag={1}&IdType={2}&ItemId={3}&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers&SearchIndex=All&Service=AWSECommerceService&Timestamp={4}&Signature={5}";
private const string FORMAT_STRING_TO_SIGN =
"GET\nwebservices.amazon.com\n/onca/xml\nAWSAccessKeyId={0}&AssociateTag={1}&IdType={2}&ItemId={3}&Operation=ItemLookup&ResponseGroup=Images%2CItemAttributes%2COffers&SearchIndex=All&Service=AWSECommerceService&Timestamp={4}";
Constant variables
通过ItemId和IdType获取商品信息:
public static async Task<AmazonItem> GetProductsById(String id, String idType)
{
try
{
String time = DateTime.Now.ToUniversalTime().ToString(FORMAT_SORTABLE_TIME);
String stringToSign = String.Format(FORMAT_STRING_TO_SIGN, AWS_ACCESS_KEY_ID, AWS_ASSOCIATE_TAG, idType, id, WebUtility.UrlEncode(time));
IBuffer buffMsg;
CryptographicKey hmacKey;
IBuffer buffHMAC;
String hmac = createHMAC(stringToSign, HASH_ALGORITHM_NAME, AWS_SECRET_KEY, out buffMsg, out hmacKey, out buffHMAC);
String url = String.Format(ENDPOINT_ITEM_SEARCH_BY_PRODUCT_ID,
AWS_ACCESS_KEY_ID, AWS_ASSOCIATE_TAG, idType, id, WebUtility.UrlEncode(time), WebUtility.UrlEncode(hmac)); HttpClient httpClient = new HttpClient(); HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
req.Headers.AcceptEncoding.Clear(); HttpResponseMessage resp = await httpClient.SendRequestAsync(req);
String responseStr = "";
if (resp.IsSuccessStatusCode)
{
IBuffer buf = await resp.Content.ReadAsBufferAsync();
responseStr = Encoding.UTF8.GetString(buf.ToArray());
}
if (String.IsNullOrEmpty(responseStr))
return null; //Get data form xml string.
LookupResponse response = null;
try
{
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(responseStr)))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(LookupResponse));
response = xmlSerializer.Deserialize(stream) as LookupResponse;
}
}
catch (Exception)
{
return null;
} if (response == null || response.Items == null || response.Items.Count <= )
return null;
return response.Items[];
}
catch
{
return null;
}
}
GetProductsById
中间有一个签名的过程需要用到HMAC的方法:
private static String createHMAC(String strMsg, String strAlgName, String key, out IBuffer buffMsg, out CryptographicKey hmacKey, out IBuffer buffMAC)
{
MacAlgorithmProvider objMacProv = MacAlgorithmProvider.OpenAlgorithm(strAlgName);
String strNameUsed = objMacProv.AlgorithmName;
BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;
buffMsg = CryptographicBuffer.ConvertStringToBinary(strMsg, encoding);
IBuffer buffKeyMaterail = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
hmacKey = objMacProv.CreateKey(buffKeyMaterail);
buffMAC = CryptographicEngine.Sign(hmacKey, buffMsg);
return CryptographicBuffer.EncodeToBase64String(buffMAC);
}
createHMAC
经过这些过程,就可以拿到Amazon的数据了,至于sample code中的LookupResponse如何构造,请参考AWS API以及Response返回数据。
后记
关于Barcode的处理还要看实际的应用场景,本文只是通过举例提到针对某些场景的处理方式,欢迎大家多多交流经验。
关于淘宝是否有对外开放的API,我本人并没有调研或者使用过,如果有的话,希望大家分享一下开发经验,谢谢!
Links
给你的应用“一只”智慧的眼睛 —— Barcode常识普及以及识别信息处理的更多相关文章
- 前端每日实战:103# 视频演示如何用纯 CSS 创作一只监视眼
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/GBzLdy 可交互视频 此视频是可 ...
- 精通Web Analytics 2.0 (4) 第二章:选择你的网络分析灵魂伴侣的最佳策略
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第二章:选择你的网络分析灵魂伴侣的最佳策略 在Web Analytics 2.0的新世界秩序中,您必须跳出"单一真理来 ...
- CSS hack常用方案(摘选)
邮箱因为默认了line-height?:170%,导致采用table元素时继承问题,可以采用line-height:50% 很好解决. 常 在使用float时,后面的显示不正常,因为继承了float了 ...
- 【总结整理】AI产品经理大会2017(转载)
从企业大数据到企业 AI | 易观智慧院院长 李智 1.AI 不是目的,而是要了解 AI 是什么,真正意义上的强人工智能在前沿领域尚未取得突破,暂时只能在影视文学作品中去思考人机关系.机器人三定律在未 ...
- KaiWu 的体验
KaiWu 的体验 来源 https://www.zhihu.com/question/28950444 >>>>>>>>>>>> ...
- javascript 框架、根基技巧、布局、CSS、控件 JavaScript 类库
预筹备之 JavaScript 今朝支流的 JavaScript 框架排名中,jQuery 和 Ext 可算是佼佼者,得到了用户的普遍好评.海内的一些框架许多也是模仿 jQuery 对 JavaScr ...
- CSS中加号、星号及其他符号的作用
在理想世界里,正确的CSS应该在任何支持CSS的浏览器里工作良好.不幸的是, 我们并不是生活在理想的世界里,浏览 器们布满了BUG和不一致.创建一个跨浏览器并且显示一致的页面,CSS开发者必须想尽办法 ...
- Linux 路线 推荐
1.<Linux程序设计>- 靠它来入门,然后装一个linux体系,练习shell(party)和linuxC,把基础打牢: 2. <深入理解Linux内核>和<Linu ...
- 如何用ABBYY FineReader识别图片中的文本
ABBYY FineReader 12是一款OCR光学字符识别软件,能够快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜索的文本,让电脑处理更具效率,摆脱从前的烦恼,告别耗时费力 ...
随机推荐
- SQL2005 表分区亲测
--增加文件组 alter database Test add filegroup [FG1] go alter database Test add filegroup [FG2] GO alter ...
- 杨氏矩阵:查找x是否在矩阵中,第K大数
参考:http://xudacheng06.blog.163.com/blog/static/4894143320127891610158/ 杨氏矩阵(Young Tableau)是一个很奇妙的数据结 ...
- CSS 代码技巧与维护 ★ Mozilla Hacks – the Web developer blog
原文链接:https://hacks.mozilla.org/2016/05/css-coding-techniques/ 译文链接 :http://www.zcfy.cc/article/css-c ...
- 我的 vim 基本配置
" required 使用 vundle 需要先设置这两项 set nocompatible filetype off " 设置 vundle 插件 使用帮助:https://gi ...
- 安装Kudu
1.默认安装好yum2.需以root身份安装3.安装ntp yum install ntp -y4.启动ntp /etc/init.d/ntpd start|stop|restart5.添加安装包yu ...
- locky勒索样本分析
前段时间收到locky样本,分析之后遂做一个分析. 样本如下所示,一般locky勒索的先决条件是一个js的脚本,脚本经过了复杂的混淆,主要用于下载该样本文件并运行,. 解密 样本本身进行了保护,通过i ...
- PDA手持机 移动开单进销存系统 现场出打印凭据和扫码 新的亮点
传统车销模式弊端:1.手写开单,效率低,动作慢2.现场手写开单明细不能打印,产品明细不规范3.电脑办公人员及车销人员对车上的库存情况掌握不清楚,销售人员对每种产品销售价格不清楚4.老板对员工工作的管控 ...
- 服务升级中的zookeeper
服务升级中zookeeper可以管理服务中的配置以及作为leader选举以及分布式事务等, 在这次主要用于配置管理,关于配置管理主要设计如下,通过zookeeper管理配置项,通过 管理界面来管理数据 ...
- Java操作属性文件之工具类
最近空闲时间整理一下平时常用的一下工具类,重复造轮子实在是浪费时间,如果不正确或者有待改善的地方,欢迎指教... package com.hsuchan.business.utils; import ...
- Java基础加强之多线程篇(线程创建与终止、互斥、通信、本地变量)
线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...