Win10/UWP 扫描二维码

Cle****-he UID.1073626
2015-12-08 发表

在Win10开发中,扫描二维码以及拍照都和以前的Windows 8.1 相同,是使用MediaCapture对象来获取图片或者视频预览数据,通过MediaCapture的CapturePhotoToStreamAsync()方法就可以拿到IRandomAccessStream流进行二维码解析或者做其他的图片操作,MediaCapture也提供了CapturePhotoToStorageFileAsync()方法来获取到IStorageFile流进行文件的操作。

下面贴下代码展示下Win10中的扫描二维码,就不一一讲解了,和以前的Windows8.1的方法类似,解析二维码用的 zxing.net 。
前台(需要注意的是用了Behaviors,记得添加 Behaviors SDK 的引用):
[mw_shl_code=csharp,true]<Page.Resources>
<Storyboard x:Name="LineStoryboard" AutoReverse="True" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="recScanning">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="-269.94"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>

<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Loaded">
<Media:ControlStoryboardAction Storyboard="{StaticResource LineStoryboard}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="LayoutRoot" >
<Grid x:Name="ContentPanel" >

<!--视频流预览-->
<CaptureElement x:Name="VideoCapture"/>

<!--Tips-->
<TextBlock x:Name="tbkTip" Foreground="White" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="36" Text="提示:请将二维码图案放置在取景框内"/>

<Grid Width="306" Height="306">
<Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Top"/>
<Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
<Rectangle Width="3" Height="50" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
<Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Top"/>
<Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
<Rectangle Width="50" Height="3" Fill="Red" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>

<Rectangle x:Name="recScanning" Margin="12,0,12,16" Height="2" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Bottom" d:LayoutOverrides="Height">
<Rectangle.RenderTransform>
<CompositeTransform/>
</Rectangle.RenderTransform>
<Rectangle.Projection>
<PlaneProjection/>
</Rectangle.Projection>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
<GradientStop Color="#331CF106" Offset="0.15"/>
<GradientStop Color="#331CF106" Offset="0.85"/>
<GradientStop Color="#FF1CF106" Offset="0.5"/>
</LinearGradientBrush>
</Rectangle.Fill>

</Rectangle>
</Grid>
</Grid>
<!--扫描结果-->
<TextBlock x:Name="tbkResult" Grid.Row="1" Foreground="White" VerticalAlignment="Top" TextWrapping="Wrap" Margin="12,18" FontSize="25" Text="扫描结果:"/>
</Grid>
</Grid>[/mw_shl_code]

后台:
[mw_shl_code=csharp,true] public sealed partial class MainPage : Page
{
private Result _result;
private readonly MediaCapture _mediaCapture = new MediaCapture();
private DispatcherTimer _timer;
private bool IsBusy;
public MainPage()
{
this.InitializeComponent();
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
InitVideoCapture();
InitVideoTimer();
}

private void InitVideoTimer()
{
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(3);
_timer.Tick += _timer_Tick;
_timer.Start();
}

private async void _timer_Tick(object sender, object e)
{
try
{
Debug.WriteLine(@"[INFO]开始扫描 -> " + DateTime.Now.ToString());
if (!IsBusy)
{
IsBusy = true;
IRandomAccessStream stream = new InMemoryRandomAccessStream();
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);

var writeableBmp = await ReadBitmap(stream, ".jpg");

await Task.Factory.StartNew(async () => { await ScanBitmap(writeableBmp); });
}
IsBusy = false;
await Task.Delay(50);
}
catch (Exception)
{
IsBusy = false;
}
}

/// <summary>
/// 保存照片
/// </summary>
/// <param name="stream"></param>
/// <param name="fileName"></param>
/// <param name="photoOrientation"></param>
/// <returns></returns>
private static async Task ReencodeAndSavePhotoAsync(IRandomAccessStream stream, string fileName, PhotoOrientation photoOrientation = PhotoOrientation.Normal)
{
using (var inputStream = stream)
{
var decoder = await BitmapDecoder.CreateAsync(inputStream);

var file = await KnownFolders.PicturesLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);

using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);

// Set the orientation of the capture
var properties = new BitmapPropertySet { { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
await encoder.BitmapProperties.SetPropertiesAsync(properties);

await encoder.FlushAsync();
}
}
}

static Guid DecoderIDFromFileExtension(string strExtension)
{
Guid encoderId;
switch (strExtension.ToLower())
{
case ".jpg":
case ".jpeg":
encoderId = BitmapDecoder.JpegDecoderId;
break;
case ".bmp":
encoderId = BitmapDecoder.BmpDecoderId;
break;
case ".png":
default:
encoderId = BitmapDecoder.PngDecoderId;
break;
}
return encoderId;
}

public static Size MaxSizeSupported = new Size(4000, 3000);

/// <summary>
/// 读取照片流 转为WriteableBitmap给二维码解码器
/// </summary>
/// <param name="fileStream"></param>
/// <param name="type"></param>
/// <returns></returns>
public async static Task<WriteableBitmap> ReadBitmap(IRandomAccessStream fileStream, string type)
{
WriteableBitmap bitmap = null;
try
{
Guid decoderId = DecoderIDFromFileExtension(type);

BitmapDecoder decoder = await BitmapDecoder.CreateAsync(decoderId, fileStream);
BitmapTransform tf = new BitmapTransform();

uint width = decoder.OrientedPixelWidth;
uint height = decoder.OrientedPixelHeight;
double dScale = 1;

if (decoder.OrientedPixelWidth > MaxSizeSupported.Width || decoder.OrientedPixelHeight > MaxSizeSupported.Height)
{
dScale = Math.Min(MaxSizeSupported.Width / decoder.OrientedPixelWidth, MaxSizeSupported.Height / decoder.OrientedPixelHeight);
width = (uint)(decoder.OrientedPixelWidth * dScale);
height = (uint)(decoder.OrientedPixelHeight * dScale);

tf.ScaledWidth = (uint)(decoder.PixelWidth * dScale);
tf.ScaledHeight = (uint)(decoder.PixelHeight * dScale);
}


bitmap = new WriteableBitmap((int)width, (int)height);



PixelDataProvider dataprovider = await decoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, tf,
ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage);
byte[] pixels = dataprovider.DetachPixelData();

Stream pixelStream2 = bitmap.PixelBuffer.AsStream();

pixelStream2.Write(pixels, 0, pixels.Length);
//bitmap.SetSource(fileStream);
}
catch
{
}

return bitmap;
}

/// <summary>
/// 解析二维码图片
/// </summary>
/// <param name="writeableBmp">图片</param>
/// <returns></returns>
private async Task ScanBitmap(WriteableBitmap writeableBmp)
{
try
{
var barcodeReader = new BarcodeReader
{
AutoRotate = true,
Options = new ZXing.Common.DecodingOptions { TryHarder = true }
};
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
_result = barcodeReader.Decode(writeableBmp);
});



if (_result != null)
{
Debug.WriteLine(@"[INFO]扫描到二维码:{result} ->" + _result.Text);
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
tbkResult.Text = _result.Text;
});
}
}
catch (Exception)
{
}
}

private async void InitVideoCapture()
{
///摄像头的检测
var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);

if (cameraDevice == null)
{
Debug.WriteLine("No camera device found!");
return;
}
var settings = new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Video,
MediaCategory = MediaCategory.Other,
AudioProcessing = Windows.Media.AudioProcessing.Default,
VideoDeviceId = cameraDevice.Id
};
await _mediaCapture.InitializeAsync(settings);
VideoCapture.Source = _mediaCapture;
await _mediaCapture.StartPreviewAsync();
}

private static async Task<DeviceInformation> FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel desiredPanel)
{
var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

DeviceInformation desiredDevice = allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredPanel);

return desiredDevice ?? allVideoDevices.FirstOrDefault();
}
}[/mw_shl_code]

效果:
***图片停止解析***

本文出自:53078485群大咖Aran

标签: 二维码

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
全部回复:
2015-12-08 回复

发这个干嘛》

前面的路 UID.932351
2015-12-08 使用 Lumia 920T 回复

期待,支持开发者

本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报