diff --git a/README.md b/README.md index 237f12f..9e853a3 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # Razor Barcode Library -A Razor Class Library, equipped with the [Dynamsoft JavaScript Barcode SDK](https://www.npmjs.com/package/dynamsoft-javascript-barcode), enables the creation of web-based barcode reader applications entirely in C#. +A Razor Class Library, equipped with the [Dynamsoft JavaScript Barcode SDK](https://www.npmjs.com/package/dynamsoft-javascript-barcode), enables the creation of web-based barcode reader and scanner applications entirely in C#. ## Online Demo [https://yushulx.me/Razor-Barcode-Library/](https://yushulx.me/Razor-Barcode-Library/) +## Demo Video https://github.com/yushulx/Razor-Barcode-Library/assets/2202306/ac3c333f-7895-420a-94ee-6debe805a8b7 @@ -12,7 +13,7 @@ https://github.com/yushulx/Razor-Barcode-Library/assets/2202306/ac3c333f-7895-42 - [Dynamsoft JavaScript Barcode License](https://www.dynamsoft.com/customer/license/trialLicense?product=dbr&utm_source=github&utm_campaign=razor-barcode-library) -## Usage +## Quick Usage - Import and initialize the Razor Barcode Library. ```csharp @@ -49,7 +50,66 @@ https://github.com/yushulx/Razor-Barcode-Library/assets/2202306/ac3c333f-7895-42 } ``` +- Create a barcode scanner instance and set the callback function. + + ```csharp + @implements BarcodeScanner.ICallback + + BarcodeReader reader = await barcodeJsInterop.CreateBarcodeScanner(); + await scanner.RegisterCallback(this); + + public async Task OnCallback(List results) {} + ``` +- Open the camera and start scanning. + + ```csharp +
+ + await scanner.SetVideoElement("videoContainer"); + List cameras = await scanner.GetCameras(); + await scanner.OpenCamera(cameras[0]); + ``` + +## API + +### Camera Class +Represents a camera device with its device ID and label. + +### BarcodeResult Class +Represents the result of a barcode scan, including the decoded text, format, and positional details. + +### BarcodeJsInterop Class + +Provides JavaScript interop functionalities for barcode operations. + +- `Task LoadJS()`: Loads and initializes the JavaScript module. +- `Task SetLicense(string license)`: Sets the license key for the barcode functionality. +- `Task LoadWasm()`: Loads the WebAssembly for barcode processing. +- `Task CreateBarcodeReader()`: Creates a new BarcodeReader instance. +- `Task CreateBarcodeScanner()`: Creates a new BarcodeScanner instance. +- `Task DrawCanvas(string id, int sourceWidth, int sourceHeight, List results)`: Draws the barcode results on a specified canvas. +- `Task ClearCanvas(string id)`: Clears the specified canvas element. + +### BarcodeReader Class + +Provides functionalities to decode barcodes from various sources such as Base64 strings and canvas objects. + +- `Task> DecodeBase64(string base64)`: Asynchronously decodes a barcode from a Base64 encoded string. +- `Task> DecodeCanvas(IJSObjectReference canvas)`: Asynchronously decodes a barcode from a canvas object. +- `Task GetParameters()`: Asynchronously retrieves the current parameters of the barcode reader. +- `Task SetParameters(string parameters)`: Asynchronously sets the parameters for the barcode reader. + +### BarcodeScanner Class + +Provides functionalities for barcode scanning using a camera. + +- `Task SetVideoElement(string videoId)`: Sets a div element as the video container. +- `Task OpenCamera(Camera camera)`: Opens the camera for barcode scanning. +- `Task CloseCamera()`: Closes the current camera. +- `Task> GetCameras()`: Gets a list of available cameras. +- `Task RegisterCallback(ICallback callback)`: Registers a callback for handling barcode scan results. + ## Example - [Blazor WebAssembly](https://github.com/yushulx/Razor-Barcode-Library/tree/main/example) - ![razor barcode reader](https://user-images.githubusercontent.com/2202306/282373638-b2cf96db-8466-4c3a-a802-4fd39cec42cd.png) + ![razor barcode reader](https://user-images.githubusercontent.com/2202306/282373638-b2cf96db-8466-4c3a-a802-4fd39cec42cd.png) \ No newline at end of file diff --git a/RazorBarcodeLibrary/BarcodeJsInterop.cs b/RazorBarcodeLibrary/BarcodeJsInterop.cs index 21ac543..877e678 100644 --- a/RazorBarcodeLibrary/BarcodeJsInterop.cs +++ b/RazorBarcodeLibrary/BarcodeJsInterop.cs @@ -2,40 +2,66 @@ namespace RazorBarcodeLibrary { + /// + /// Provides JavaScript interop functionalities for barcode operations. + /// public class BarcodeJsInterop : IAsyncDisposable { + // Holds a task that resolves to a JavaScript module reference. private readonly Lazy> moduleTask; + /// + /// Initializes a new instance of the BarcodeJsInterop class. + /// + /// The JS runtime to use for invoking JavaScript functions. public BarcodeJsInterop(IJSRuntime jsRuntime) { moduleTask = new(() => jsRuntime.InvokeAsync( "import", "./_content/RazorBarcodeLibrary/barcodeJsInterop.js").AsTask()); } + /// + /// Loads and initializes the JavaScript module. + /// public async Task LoadJS() { var module = await moduleTask.Value; await module.InvokeAsync("init"); } + /// + /// Sets the license key for the barcode functionality. + /// + /// The license key. public async Task SetLicense(string license) { var module = await moduleTask.Value; await module.InvokeVoidAsync("setLicense", license); } + /// + /// Loads the WebAssembly for barcode processing. + /// public async Task LoadWasm() { var module = await moduleTask.Value; await module.InvokeVoidAsync("loadWasm"); } + /// + /// Gets the version of the barcode library. + /// + /// A task that represents the asynchronous operation. The task result contains the version string. public async ValueTask GetVersion() { var module = await moduleTask.Value; return await module.InvokeAsync("getVersion"); } + /// + /// Creates a new BarcodeReader instance. + /// + /// A task that represents the asynchronous operation. The task result is a new BarcodeReader instance. public async Task CreateBarcodeReader() { var module = await moduleTask.Value; @@ -44,6 +70,10 @@ public async Task CreateBarcodeReader() return reader; } + /// + /// Creates a new BarcodeScanner instance. + /// + /// A task that represents the asynchronous operation. The task result is a new BarcodeScanner instance. public async Task CreateBarcodeScanner() { var module = await moduleTask.Value; @@ -52,6 +82,11 @@ public async Task CreateBarcodeScanner() return scanner; } + /// + /// Converts a Base64 string to a canvas element. + /// + /// The Base64 encoded string. + /// A task that represents the asynchronous operation. The task result is a reference to the canvas element. public async Task Base64ToCanvas(string base64) { var module = await moduleTask.Value; @@ -59,18 +94,32 @@ public async Task Base64ToCanvas(string base64) return canvas; } + /// + /// Draws the barcode results on a specified canvas. + /// + /// The ID of the canvas element. + /// The width of the source image. + /// The height of the source image. + /// The list of barcode results to draw. public async Task DrawCanvas(string id, int sourceWidth, int sourceHeight, List results) { var module = await moduleTask.Value; await module.InvokeVoidAsync("drawCanvas", id, sourceWidth, sourceHeight, results); } + /// + /// Clears the specified canvas element. + /// + /// The ID of the canvas element to clear. public async Task ClearCanvas(string id) { var module = await moduleTask.Value; await module.InvokeVoidAsync("clearCanvas", id); } + /// + /// Releases unmanaged resources asynchronously. + /// public async ValueTask DisposeAsync() { if (moduleTask.IsValueCreated) diff --git a/RazorBarcodeLibrary/BarcodeReader.cs b/RazorBarcodeLibrary/BarcodeReader.cs index 47ca208..72e0e35 100644 --- a/RazorBarcodeLibrary/BarcodeReader.cs +++ b/RazorBarcodeLibrary/BarcodeReader.cs @@ -3,19 +3,34 @@ namespace RazorBarcodeLibrary { + /// + /// Provides functionalities to decode barcodes from various sources and manage barcode reader settings. + /// public class BarcodeReader { + // Fields to hold JavaScript object references. private IJSObjectReference _module; private IJSObjectReference _jsObjectReference; + // Public properties to store source dimensions. public int SourceWidth, SourceHeight; + /// + /// Initializes a new instance of the BarcodeReader class. + /// + /// A reference to the JavaScript module. + /// A reference to the JavaScript object for barcode reading. public BarcodeReader(IJSObjectReference module, IJSObjectReference reader) { _module = module; _jsObjectReference = reader; } + /// + /// Asynchronously decodes a barcode from a Base64 encoded string. + /// + /// The Base64 encoded string containing the barcode image. + /// A task that represents the asynchronous decode operation. The task result contains a list of BarcodeResult objects. public async Task> DecodeBase64(string base64) { JsonElement? result = await _jsObjectReference.InvokeAsync("decode", base64); @@ -24,6 +39,11 @@ public async Task> DecodeBase64(string base64) return BarcodeResult.WrapResult(result); } + /// + /// Asynchronously decodes a barcode from a canvas object. + /// + /// A reference to the JavaScript object representing the canvas with the barcode image. + /// A task that represents the asynchronous decode operation. The task result contains a list of BarcodeResult objects. public async Task> DecodeCanvas(IJSObjectReference canvas) { JsonElement? result = await _jsObjectReference.InvokeAsync("decode", canvas); @@ -32,6 +52,10 @@ public async Task> DecodeCanvas(IJSObjectReference canvas) return BarcodeResult.WrapResult(result); } + /// + /// Asynchronously retrieves the current parameters of the barcode reader. + /// + /// A task that represents the asynchronous operation. The task result is a string representation of the current barcode reader settings. public async Task GetParameters() { if (_jsObjectReference == null) { return ""; } @@ -39,6 +63,11 @@ public async Task GetParameters() return await _jsObjectReference.InvokeAsync("outputRuntimeSettingsToString"); } + /// + /// Asynchronously sets the parameters for the barcode reader. + /// + /// A string representation of the settings to apply to the barcode reader. + /// A task that represents the asynchronous operation. The task result is an integer indicating the status (0 for success, -1 for failure). public async Task SetParameters(string parameters) { if (_jsObjectReference == null) { return -1; } diff --git a/RazorBarcodeLibrary/BarcodeResult.cs b/RazorBarcodeLibrary/BarcodeResult.cs index dcbd547..2ec4eab 100644 --- a/RazorBarcodeLibrary/BarcodeResult.cs +++ b/RazorBarcodeLibrary/BarcodeResult.cs @@ -2,13 +2,27 @@ namespace RazorBarcodeLibrary { + /// + /// Represents the result of a barcode scan, including the decoded text, format, and positional details. + /// public class BarcodeResult { + /// + /// Gets or sets the decoded text of the barcode. + /// public string Text { get; set; } = string.Empty; + + /// + /// Gets or sets the format of the decoded barcode. + /// public string Format { get; set; } = string.Empty; + /// + /// Gets or sets the full information string of the barcode result. + /// public string FullInfo { get; set; } = string.Empty; + // Properties for the coordinates of the barcode corners public int X1 { get; set; } public int Y1 { get; set; } public int X2 { get; set; } @@ -18,12 +32,19 @@ public class BarcodeResult public int X4 { get; set; } public int Y4 { get; set; } - + /// + /// Returns a string that represents the current barcode result. + /// + /// A string representation of the barcode result. public override string ToString() { return $"Text: {Text}, Format: {Format}, X1: {X1}, Y1: {Y1}, X2: {X2}, Y2: {Y2}, X3: {X3}, Y3: {Y3}, X4: {X4}, Y4: {Y4}"; } + /// + /// Converts the barcode result into a JSON formatted dictionary. + /// + /// A dictionary containing the barcode result data in JSON format. public Dictionary ToJson() { var jsonDict = new Dictionary(); @@ -40,6 +61,11 @@ public override string ToString() return jsonDict; } + /// + /// Static method to wrap JSON results into a list of BarcodeResult objects. + /// + /// The JSON element containing the barcode scan results. + /// A list of BarcodeResult objects representing the scan results. public static List WrapResult(JsonElement? result) { List results = new List(); diff --git a/RazorBarcodeLibrary/BarcodeScanner.cs b/RazorBarcodeLibrary/BarcodeScanner.cs index a9b31a4..7b8ff8f 100644 --- a/RazorBarcodeLibrary/BarcodeScanner.cs +++ b/RazorBarcodeLibrary/BarcodeScanner.cs @@ -3,21 +3,43 @@ namespace RazorBarcodeLibrary { + /// + /// Represents a camera device with its device ID and label. + /// public class Camera { + /// + /// Gets or sets the unique device identifier for the camera. + /// public string DeviceId { get; set; } = string.Empty; + + /// + /// Gets or sets the label of the camera. + /// public string Label { get; set; } = string.Empty; } + + /// + /// Provides functionalities for barcode scanning using a camera. + /// public class BarcodeScanner : IDisposable { + // Private fields for JavaScript object references and internal state private IJSObjectReference _module; private IJSObjectReference _jsObjectReference; private List _cameras = new List(); private ICallback? _callback; private DotNetObjectReference objRef; private bool _disposed = false; + + // Public properties for source dimensions public int SourceWidth, SourceHeight; + /// + /// Initializes a new instance of the BarcodeScanner class. + /// + /// A reference to the JavaScript module. + /// A reference to the JavaScript object for barcode scanning. public BarcodeScanner(IJSObjectReference module, IJSObjectReference scanner) { _module = module; @@ -25,21 +47,36 @@ public BarcodeScanner(IJSObjectReference module, IJSObjectReference scanner) objRef = DotNetObjectReference.Create(this); } + /// + /// Sets a div element as the video container. + /// + /// The ID of the div element. public async Task SetVideoElement(string videoId) { await _module.InvokeVoidAsync("setVideoElement", _jsObjectReference, videoId); } + /// + /// Opens the camera for barcode scanning. + /// + /// The camera to be used for scanning. public async Task OpenCamera(Camera camera) { await _module.InvokeVoidAsync("openCamera", _jsObjectReference, camera, objRef, "OnSizeChanged"); } + /// + /// Closes the current camera. + /// public async Task CloseCamera() { await _module.InvokeVoidAsync("closeCamera", _jsObjectReference); } + /// + /// Gets a list of available cameras. + /// + /// A list of available Camera objects. public async Task> GetCameras() { JsonElement? result = await _module.InvokeAsync("getCameras", _jsObjectReference); @@ -78,11 +115,18 @@ public async Task> GetCameras() return _cameras; } + /// + /// Interface for barcode scanner callback. + /// public interface ICallback { Task OnCallback(List results); } + /// + /// Invoked when barcode scan results are ready. + /// + /// The scan result data. [JSInvokable] public Task OnResultReady(object message) { @@ -95,6 +139,11 @@ public Task OnResultReady(object message) return Task.CompletedTask; } + /// + /// Invoked when the size of the video source changes. + /// + /// The new width of the video source. + /// The new height of the video source. [JSInvokable] public Task OnSizeChanged(int width, int height) { @@ -104,12 +153,19 @@ public Task OnSizeChanged(int width, int height) return Task.CompletedTask; } + /// + /// Registers a callback for handling barcode scan results. + /// + /// The callback to register. public async Task RegisterCallback(ICallback callback) { _callback = callback; await _module.InvokeVoidAsync("registerCallback", _jsObjectReference, objRef, "OnResultReady"); } + /// + /// Release unmanaged resources. + /// public void Dispose() { if (_disposed == false) @@ -119,6 +175,9 @@ public void Dispose() } } + /// + /// Destructor for the BarcodeScanner class. + /// ~BarcodeScanner() { if (_disposed == false) diff --git a/RazorBarcodeLibrary/RazorBarcodeLibrary.csproj b/RazorBarcodeLibrary/RazorBarcodeLibrary.csproj index 3f2167e..9b108d4 100644 --- a/RazorBarcodeLibrary/RazorBarcodeLibrary.csproj +++ b/RazorBarcodeLibrary/RazorBarcodeLibrary.csproj @@ -2,7 +2,7 @@ RazorBarcodeLibrary - 0.1.1 + 1.0.0 yushulx Dynamsoft net7.0 @@ -16,7 +16,7 @@ barcode;qrcode;pdf417;datamatrix;csharp;blazor;dotnet;aztec;code39;code128;ean13 - - Updated README.md. + - Added barcode scanner API. MIT true diff --git a/example/Pages/Index.razor b/example/Pages/Index.razor index b81c9ff..7919ab4 100644 --- a/example/Pages/Index.razor +++ b/example/Pages/Index.razor @@ -146,7 +146,6 @@ isLoading = true; IJSObjectReference canvas = await barcodeJsInterop.Base64ToCanvas(imageSrc); // List results = await reader.DecodeCanvas(canvas); - List results = await reader.DecodeBase64(imageSrc); if (results.Count > 0) {