Files
win8phoneApp/CampusAppWP8/CampusAppWP8/Pages/Dev/QRScanner.xaml.cs
2013-10-02 12:01:46 +02:00

276 lines
9.4 KiB
C#

//-----------------------------------------------------------------------------
// <copyright file="QRScanner.xaml.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>fiedlchr</author>
// <sience>15.08.2013</sience>
// <remarks>
// This Class uses the ZXing library, which is under the Apache License 2.0.
//
// Therefor, see:
// http://zxingnet.codeplex.com/license
// http://www.apache.org/licenses/LICENSE-2.0
// </remarks>
//-----------------------------------------------------------------------------
namespace CampusAppWP8.Pages.Dev
{
using System;
using System.Threading;
using System.Windows;
using System.Windows.Media.Imaging;
using CampusAppWP8.Resources;
using CampusAppWP8.Utility;
using Microsoft.Devices;
using Microsoft.Phone.Controls;
using ZXing;
/// <summary>
/// QR Code scanner.
/// </summary>
public partial class QRScanner : PhoneApplicationPage
{
#region Member
/// <summary>The camera object.</summary>
private PhotoCamera cam = null;
/// <summary>Thread for transfer the preview image to the reader.</summary>
private Thread captureThread = null;
/// <summary>For ending the thread.</summary>
private volatile bool captureThreadExit = false;
/// <summary>QR reader object.</summary>
private IBarcodeReader barcodeReader = null;
/// <summary>Bitmap for transfer the camera image to the reader.</summary>
private WriteableBitmap bit = null;
/// <summary>true if this object is in autofocus. </summary>
private bool isInAutofocus = false;
/// <summary>
/// Variable for the storage key of the result
/// </summary>
private string resultAppStoreKey;
#endregion
#region Constructor
/// <summary>Initializes a new instance of the <see cref="QRScanner" /> class. </summary>
public QRScanner()
{
this.InitializeComponent();
this.barcodeReader = new BarcodeReader();
}
#endregion
#region Method
#region protected
/// <summary>
/// Is called when this page will become the current page of a frame.
/// </summary>
/// <param name="e">event args.</param>
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary) == true)
{
if (NavigationContext.QueryString.ContainsKey(Constants.ParamQRResultKey))
{
this.resultAppStoreKey = NavigationContext.QueryString[Constants.ParamQRResultKey];
}
this.isInAutofocus = true;
this.cam = new PhotoCamera(CameraType.Primary);
this.cam.Initialized += new EventHandler<CameraOperationCompletedEventArgs>(this.Cam_Initialized);
this.cam.AutoFocusCompleted += new EventHandler<CameraOperationCompletedEventArgs>(this.Cam_AutoFocusCompl);
this.bit = new WriteableBitmap((int)this.cam.PreviewResolution.Width, (int)this.cam.PreviewResolution.Height);
this.camViewBrush.SetSource(this.cam);
}
else
{
this.Dispatcher.BeginInvoke(delegate
{
MessageBox.Show(AppResources.PrimCamNotSupported);
});
}
}
/// <summary>
/// Is called when this page will not be the current page of a frame.
/// </summary>
/// <param name="e">event args.</param>
protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
if (this.cam != null)
{
this.captureThreadExit = true;
this.captureThread.Join();
this.cam.Dispose();
this.bit = null;
}
}
/// <summary>
/// Is called after the orientation has changed.
/// </summary>
/// <param name="e">event args.</param>
protected override void OnOrientationChanged(OrientationChangedEventArgs e)
{
base.OnOrientationChanged(e);
switch (e.Orientation)
{
case PageOrientation.Landscape:
this.camViewBrushTransform.Rotation = 0;
break;
case PageOrientation.LandscapeLeft:
this.camViewBrushTransform.Rotation = 0;
break;
case PageOrientation.LandscapeRight:
this.camViewBrushTransform.Rotation = 180;
break;
case PageOrientation.Portrait:
this.camViewBrushTransform.Rotation = 90;
break;
case PageOrientation.PortraitUp:
this.camViewBrushTransform.Rotation = 90;
break;
case PageOrientation.PortraitDown:
this.camViewBrushTransform.Rotation = 270;
break;
}
}
#endregion
#region private
/// <summary>
/// Event handler. Called by Cam for initialized events.
/// </summary>
/// <param name="sender">Source of the event.</param>
/// <param name="e">Camera operation completed event information.</param>
private void Cam_Initialized(object sender, Microsoft.Devices.CameraOperationCompletedEventArgs e)
{
if (e.Succeeded)
{
this.cam.Focus();
this.captureThreadExit = false;
this.captureThread = new Thread(this.CaptureThreadFunc);
this.captureThread.Start();
}
}
/// <summary>
/// Event handler. Called by Cam for automatic focus completed events.
/// </summary>
/// <param name="sender">Source of the event.</param>
/// <param name="e">Camera operation completed event information.</param>
private void Cam_AutoFocusCompl(object sender, CameraOperationCompletedEventArgs e)
{
//this.isInAutofocus = false;
}
/// <summary>
/// Event handler. Called by CamView for tap events.
/// </summary>
/// <param name="sender">Source of the event.</param>
/// <param name="e">Gesture event information.</param>
private void CamView_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (this.cam != null && this.isInAutofocus == false)
{
if (this.cam.IsFocusAtPointSupported == true)
{
Point pos = e.GetPosition(this.camView);
this.cam.FocusAtPoint(
pos.Y / this.camView.ActualHeight,
1.0 - (pos.X / this.camView.ActualWidth));
}
else if (this.cam.IsFocusSupported == true)
{
this.cam.Focus();
}
}
}
/// <summary>
/// Executes the capture image action.
/// </summary>
/// <param name="img">The image.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
private void OnCaptureImage(int[] img, int width, int height)
{
Array.Copy(img, this.bit.Pixels, img.Length);
var result = this.barcodeReader.Decode(this.bit);
if (result != null)
{
Dispatcher.BeginInvoke(delegate
{
if (this.resultAppStoreKey != null)
{
if (NavigationService.CanGoBack)
{
App.SaveToIsolatedStorage(this.resultAppStoreKey, result.Text);
NavigationService.GoBack();
}
else
{
string pid = Wp8StringManager.FilterPlaceIdinQRResultString(result.Text);
string urlString = Constants.PathCampusmap_Campusmap;
urlString += "?" + Constants.ParamModelMap_SearchTermAlias + "=" + pid;
Uri url = new Uri(urlString as string, UriKind.Relative);
NavigationService.Navigate(url);
}
}
else
{
MessageBox.Show(result.Text);
}
});
}
else
{
this.cam.Focus();
}
}
/// <summary>
/// Capture thread function.
/// </summary>
private void CaptureThreadFunc()
{
Size resolution = this.cam.PreviewResolution;
int[] buffer = new int[(int)(resolution.Height * resolution.Width)];
while (!this.captureThreadExit)
{
//if (this.isInAutofocus == false)
//{
this.cam.GetPreviewBufferArgb32(buffer);
this.OnCaptureImage(buffer, (int)resolution.Width, (int)resolution.Height);
this.isInAutofocus = true;
//}
System.Threading.Thread.Sleep(1000);
}
}
#endregion
#endregion
}
}