diff --git a/plugin.xml b/plugin.xml index 7b1e77430..98af9f4c6 100644 --- a/plugin.xml +++ b/plugin.xml @@ -40,31 +40,24 @@ - - + + + - - - - - - - - - - - - + + + - - - - - - + + + + + + + diff --git a/src/ios/CDVBarcodeScanner.mm b/src/ios/CDVBarcodeScanner.mm index c7ccc7d82..8807c9121 100644 --- a/src/ios/CDVBarcodeScanner.mm +++ b/src/ios/CDVBarcodeScanner.mm @@ -48,7 +48,7 @@ @interface CDVBarcodeScanner : CDVPlugin {} - (NSString*)isScanNotPossible; - (void)scan:(CDVInvokedUrlCommand*)command; - (void)encode:(CDVInvokedUrlCommand*)command; -- (void)returnSuccess:(NSString*)scannedText format:(NSString*)format cancelled:(BOOL)cancelled callback:(NSString*)callback; +- (void)returnSuccess:(NSString*)scannedText format:(NSString*)format cancelled:(BOOL)cancelled flipped:(BOOL)flipped callback:(NSString*)callback; - (void)returnError:(NSString*)message callback:(NSString*)callback; @end @@ -66,6 +66,9 @@ @interface CDVbcsProcessor : NSObject - { - currentRootVisual = Application.Current.RootVisual as PhoneApplicationFrame; - currentRootVisual.Navigated += OnFrameNavigated; - currentRootVisual.Navigate(new Uri("/Plugins/com.phonegap.plugins.barcodescanner/Scan.xaml", UriKind.Relative)); - }); - } - - private void OnFrameNavigated(object sender, NavigationEventArgs e) - { - var scanPage = e.Content as Scan; - if (scanPage != null) - { - scanPage.BarcodeScannerPlugin = this; - } - } - - public void OnScanFailed(string error) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, error)); - } - - public void OnScanSucceeded(BarcodeScannerResult scanResult) - { - var resultString = JsonHelper.Serialize(scanResult); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, resultString)); - } - } -} diff --git a/src/wp/BarcodeScannerResult.cs b/src/wp/BarcodeScannerResult.cs deleted file mode 100644 index 87c052bad..000000000 --- a/src/wp/BarcodeScannerResult.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BarcodeScanner -{ - public class BarcodeScannerResult - { - public string format - { - get; - set; - } - - public string text - { - get; - set; - } - } -} diff --git a/src/wp/Scan.xaml b/src/wp/Scan.xaml deleted file mode 100644 index af9f5ef7c..000000000 --- a/src/wp/Scan.xaml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/wp/Scan.xaml.cs b/src/wp/Scan.xaml.cs deleted file mode 100644 index d9bc14dad..000000000 --- a/src/wp/Scan.xaml.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Navigation; -using Microsoft.Phone.Controls; -using Microsoft.Phone.Shell; -using Microsoft.Devices; -using System.Windows.Threading; -using System.Windows.Media.Imaging; -using ZXing; - -namespace BarcodeScanner -{ - public partial class Scan : PhoneApplicationPage - { - private PhotoCamera phoneCamera; - private IBarcodeReader barcodeReader; - private DispatcherTimer scanTimer; - private WriteableBitmap previewBuffer; - - private string scannedCode = string.Empty; - - private bool scanSucceeded; - - public Scan() - { - InitializeComponent(); - } - - public Cordova.Extension.Commands.BarcodeScanner BarcodeScannerPlugin - { - get; - set; - } - - protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) - { - // Initialize the camera object - phoneCamera = new PhotoCamera(); - phoneCamera.Initialized += OnCameraInitialized; - - CameraButtons.ShutterKeyHalfPressed += OnCameraButtonShutterKeyHalfPressed; - - //Display the camera feed in the UI - viewfinderBrush.SetSource(phoneCamera); - - - // This timer will be used to scan the camera buffer every 250ms and scan for any barcodes - scanTimer = new DispatcherTimer(); - scanTimer.Interval = TimeSpan.FromMilliseconds(250); - scanTimer.Tick += (o, arg) => ScanForBarcode(); - - base.OnNavigatedTo(e); - } - - private void OnCameraButtonShutterKeyHalfPressed(object sender, EventArgs e) - { - phoneCamera.Focus(); - } - - protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e) - { - scanTimer.Stop(); - - if (phoneCamera != null) - { - phoneCamera.Dispose(); - phoneCamera.Initialized -= OnCameraInitialized; - CameraButtons.ShutterKeyHalfPressed -= OnCameraButtonShutterKeyHalfPressed; - } - - if (!scanSucceeded) - { - BarcodeScannerPlugin.OnScanFailed("Cancelled by user"); - } - } - - void OnCameraInitialized(object sender, Microsoft.Devices.CameraOperationCompletedEventArgs e) - { - if (e.Succeeded) - { - this.Dispatcher.BeginInvoke(delegate() - { - phoneCamera.FlashMode = FlashMode.Off; - previewBuffer = new WriteableBitmap((int)phoneCamera.PreviewResolution.Width, (int)phoneCamera.PreviewResolution.Height); - - barcodeReader = new BarcodeReader(); - - // By default, BarcodeReader will scan every supported barcode type - // If we want to limit the type of barcodes our app can read, - // we can do it by adding each format to this list object - - //var supportedBarcodeFormats = new List(); - //supportedBarcodeFormats.Add(BarcodeFormat.QR_CODE); - //supportedBarcodeFormats.Add(BarcodeFormat.DATA_MATRIX); - //_bcReader.PossibleFormats = supportedBarcodeFormats; - - barcodeReader.Options.TryHarder = true; - - barcodeReader.ResultFound += OnBarcodeResultFound; - scanTimer.Start(); - }); - } - else - { - Dispatcher.BeginInvoke(() => - { - BarcodeScannerPlugin.OnScanFailed("Unable to initialize the camera"); - }); - } - } - - private void OnBarcodeResultFound(Result obj) - { - if (BarcodeIsValid(obj.Text)) - { - var barcodeScannerResult = new BarcodeScannerResult(); - barcodeScannerResult.format = obj.BarcodeFormat.ToString(); - barcodeScannerResult.text = obj.Text; - scanSucceeded = true; - - BarcodeScannerPlugin.OnScanSucceeded(barcodeScannerResult); - NavigationService.GoBack(); - } - } - - private bool BarcodeIsValid(string barcode) - { - if (barcode.Equals(scannedCode)) - { - return false; - } - - return true; - } - - private void ScanForBarcode() - { - //grab a camera snapshot - phoneCamera.GetPreviewBufferArgb32(previewBuffer.Pixels); - previewBuffer.Invalidate(); - - //scan the captured snapshot for barcodes - //if a barcode is found, the ResultFound event will fire - barcodeReader.Decode(previewBuffer); - } - } -} \ No newline at end of file diff --git a/src/wp8/BarcodeScanner.cs b/src/wp8/BarcodeScanner.cs new file mode 100644 index 000000000..b3e32d641 --- /dev/null +++ b/src/wp8/BarcodeScanner.cs @@ -0,0 +1,46 @@ +using System; +using System.Windows; +using System.Windows.Navigation; +using BarcodeScanner; +using Microsoft.Phone.Controls; +using WPCordovaClassLib.Cordova; +using WPCordovaClassLib.Cordova.Commands; +using WPCordovaClassLib.Cordova.JSON; + +namespace Cordova.Extension.Commands +{ + public class BarcodeScanner : BaseCommand + { + private PhoneApplicationFrame currentRootVisual; + + public void scan(string options) + { + Deployment.Current.Dispatcher.BeginInvoke(() => + { + this.currentRootVisual = Application.Current.RootVisual as PhoneApplicationFrame; + this.currentRootVisual.Navigated += this.OnFrameNavigated; + this.currentRootVisual.Navigate(new Uri("/Plugins/com.phonegap.plugins.barcodescanner/Scan.xaml", UriKind.Relative)); + }); + } + + public void OnScanFailed(string error) + { + this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, error)); + } + + public void OnScanSucceeded(BarcodeScannerResult scanResult) + { + var resultString = JsonHelper.Serialize(scanResult); + this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, resultString)); + } + + private void OnFrameNavigated(object sender, NavigationEventArgs e) + { + var scanPage = e.Content as Scan; + if (scanPage != null) + { + scanPage.BarcodeScannerPlugin = this; + } + } + } +} \ No newline at end of file diff --git a/src/wp8/BarcodeScannerResult.cs b/src/wp8/BarcodeScannerResult.cs new file mode 100644 index 000000000..4624e577d --- /dev/null +++ b/src/wp8/BarcodeScannerResult.cs @@ -0,0 +1,16 @@ +using System; +using System.Linq; +using System.Runtime.Serialization; + +namespace BarcodeScanner +{ + [DataContract] + public class BarcodeScannerResult + { + [DataMember(Name = "format")] + public string Format { get; set; } + + [DataMember(Name = "text")] + public string Text { get; set; } + } +} \ No newline at end of file diff --git a/src/wp8/Scan.xaml b/src/wp8/Scan.xaml new file mode 100644 index 000000000..0750d56ce --- /dev/null +++ b/src/wp8/Scan.xaml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/wp8/Scan.xaml.cs b/src/wp8/Scan.xaml.cs new file mode 100644 index 000000000..f12178989 --- /dev/null +++ b/src/wp8/Scan.xaml.cs @@ -0,0 +1,149 @@ +using System; +using System.Windows.Media.Imaging; +using System.Windows.Threading; +using Microsoft.Devices; +using Microsoft.Phone.Controls; +using ZXing; + +namespace BarcodeScanner +{ + public partial class Scan : PhoneApplicationPage + { + private const int SizeWriteableBitmapPixel = 4; + private const int CaptureMillisecondsInterval = 2000; + + private PhotoCamera phoneCamera; + private IBarcodeReader barcodeReader; + private DispatcherTimer scanTimer; + private WriteableBitmap previewBuffer; + private string scannedCode = string.Empty; + private bool scanSucceeded; + + public Scan() + { + this.InitializeComponent(); + } + + public Cordova.Extension.Commands.BarcodeScanner BarcodeScannerPlugin { get; set; } + + protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) + { + // Initialize the camera object + this.phoneCamera = new PhotoCamera(); + this.phoneCamera.Initialized += this.OnCameraInitialized; + + //Display the camera feed in the UI + this.viewfinderBrush.SetSource(this.phoneCamera); + + // This timer will be used to scan the camera buffer every 2000ms and scan for any barcodes + this.scanTimer = new DispatcherTimer(); + this.scanTimer.Interval = TimeSpan.FromMilliseconds(CaptureMillisecondsInterval); + this.scanTimer.Tick += (o, arg) => this.ScanForBarcode(); + + base.OnNavigatedTo(e); + } + + protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e) + { + this.scanTimer.Stop(); + + if (this.phoneCamera != null) + { + this.phoneCamera.CancelFocus(); + this.phoneCamera.Dispose(); + this.phoneCamera.Initialized -= this.OnCameraInitialized; + } + + if (!this.scanSucceeded) + { + this.BarcodeScannerPlugin.OnScanFailed("Cancelled by user"); + } + } + + private void OnCameraInitialized(object sender, Microsoft.Devices.CameraOperationCompletedEventArgs e) + { + if (e.Succeeded) + { + this.Dispatcher.BeginInvoke(delegate() + { + this.phoneCamera.FlashMode = FlashMode.Auto; + this.phoneCamera.Focus(); + + this.previewBuffer = new WriteableBitmap((int)this.phoneCamera.PreviewResolution.Width, (int)this.phoneCamera.PreviewResolution.Height); + this.barcodeReader = new BarcodeReader(); + + // By default, BarcodeReader will scan every supported barcode type + // If we want to limit the type of barcodes our app can read, + // we can do it by adding each format to this list object + + //var supportedBarcodeFormats = new List(); + //supportedBarcodeFormats.Add(BarcodeFormat.QR_CODE); + //supportedBarcodeFormats.Add(BarcodeFormat.DATA_MATRIX); + //_bcReader.PossibleFormats = supportedBarcodeFormats; + + this.barcodeReader.Options.TryHarder = true; + + this.barcodeReader.ResultFound += this.OnBarcodeResultFound; + this.scanTimer.Start(); + }); + } + else + { + this.Dispatcher.BeginInvoke(() => + { + this.BarcodeScannerPlugin.OnScanFailed("Unable to initialize the camera"); + }); + } + } + + private void OnBarcodeResultFound(Result obj) + { + if (this.BarcodeIsValid(obj.Text)) + { + var barcodeScannerResult = new BarcodeScannerResult(); + barcodeScannerResult.Format = obj.BarcodeFormat.ToString(); + barcodeScannerResult.Text = obj.Text; + this.scanSucceeded = true; + + this.BarcodeScannerPlugin.OnScanSucceeded(barcodeScannerResult); + this.NavigationService.GoBack(); + } + } + + private bool BarcodeIsValid(string barcode) + { + return !barcode.Equals(this.scannedCode); + } + + private void ScanForBarcode() + { + //try to capture barcode + this.phoneCamera.Focus(); + + //grab a camera snapshot + this.phoneCamera.GetPreviewBufferArgb32(this.previewBuffer.Pixels); + this.previewBuffer.Invalidate(); + + //look only image from focus area + var croppedBuff = this.GetCameraFocusArea((int)this.leftBlurArea.ActualWidth, (int)this.upBlurArea.ActualHeight, (int)this.focusArea.ActualHeight, (int)this.focusArea.ActualWidth); + croppedBuff.Invalidate(); + + //scan the captured snapshot for barcodes + //if a barcode is found, the ResultFound event will fire + this.barcodeReader.Decode(croppedBuff); + } + + private WriteableBitmap GetCameraFocusArea(int left, int top, int width, int height) + { + // Copy the pixels line by line using fast BlockCopy + var cropped = new WriteableBitmap(width, height); + for (var row = 0; row < height; row++) + { + var sourceOffset = ((top + row) * this.previewBuffer.PixelWidth + left) * SizeWriteableBitmapPixel; + var croppedOffset = row * width * SizeWriteableBitmapPixel; + Buffer.BlockCopy(this.previewBuffer.Pixels, sourceOffset, cropped.Pixels, croppedOffset, width * SizeWriteableBitmapPixel); + } + return cropped; + } + } +} \ No newline at end of file diff --git a/src/wp8/zxing.wp8.0.dll b/src/wp8/zxing.wp8.0.dll new file mode 100644 index 000000000..3e83a1d1d Binary files /dev/null and b/src/wp8/zxing.wp8.0.dll differ