Blazor is a web framework developed by Microsoft. It enables developers to create web apps using C# and HTML. However, calling existing JavaScript API is inevitable while developing a Blazor project. This article will help web developers who want to build web barcode and QR code reader apps using Blazor WebAssembly and Dynamsoft JavaScript Barcode SDK.
How to Use Dynamsoft JavaScript Barcode SDK
Include <script src="https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.0.0/dist/dbr.js"></script>
in your HTML file.
Apply for a 30-day trial license to activate the SDK:
Dynamsoft.DBR.BarcodeReader.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
Blazor Architecture Overview
Blazor provides two templates: Blazor WebAssembly and Blazor Server.
Blazor WebAssembly
Blazor Server
Blazor server runs client-side UI logic on the server-side and sends the UI changes via Websocket. To conveniently handle JavaScript interop calls, we pick Blazor WebAssembly to implement the web barcode and QR code reader.
New to Blazor WebAssembly Project
Create a Blazor App with the Blazor WebAssembly template:
dotnet new blazorwasm -o BlazorBarcodeSample
Then add a new page to the project:
cd BlazorBarcodeSample
dotnet new razorcomponent -n BarcodeReader -o Pages
After that, add a BarcodeReader
attribute to Pages/Index.razor
:
@page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<BarcodeReader />
So far, we can run the app and view the homepage:
dotnet run
When running the app for the first time, we can open the developer console to observe what is going on.
A dotnet.wasm
file and some *.dll files are fetched and cached by the web browser.
After making some changes and rebuild the project, we will find that only the BlazorBarcodeSample.dll
has been fetched again.
Reading Barcode and QR Code in Blazor WebAssembly
We add Dynamsoft JavaScript Barcode SDK to wwwroot/index.html
, and then create a jsInterop.js
file for interoperation between JavaScript and .NET:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>BlazorBarcodeSample</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="BlazorBarcodeSample.styles.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@9.0.0/dist/dbr.js"></script>
</head>
<body>
<script src="_framework/blazor.webassembly.js"></script>
<script src="jsInterop.js"></script>
</body>
</html>
In jsInterop.js
, we initialize Dynamsoft Barcode Reader and use a JavaScript variable to save the reference of the .NET object:
let barcodescanner = null;
let dotnetRef = null;
window.jsFunctions = {
init: function(obj) {
let result = true;
try {
Dynamsoft.DBR.BarcodeReader.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
barcodescanner = await Dynamsoft.DBR.BarcodeScanner.createInstance();
await barcodescanner.updateRuntimeSettings("balance");
dotnetRef = obj;
} catch (e) {
console.log(e);
result = false;
}
return result;
},
};
The JavaScript init()
function will be triggered by the OnInitialized()
method in BarcodeReader.razor
:
@inject IJSRuntime JSRuntime
@if (initialized == false)
{
<p>Initializing...</p>
}
else
{
}
@code {
Boolean initialized = false;
protected override void OnInitialized()
{
Init();
}
public async void Init()
{
initialized = await JSRuntime.InvokeAsync<Boolean>("jsFunctions.init", DotNetObjectReference.Create(this));
StateHasChanged();
}
}
To select an image file from the disk drive, we use the InputFile component:
<InputFile OnChange="LoadImage" />
@code {
private async Task LoadImage(InputFileChangeEventArgs e)
{
var imageFile = e.File;
var jsImageStream = imageFile.OpenReadStream(1024 * 1024 * 20);
var dotnetImageStream = new DotNetStreamReference(jsImageStream);
await JSRuntime.InvokeVoidAsync("jsFunctions.setImageUsingStreaming",
"image", dotnetImageStream);
}
}
As the image is loaded, we call the setImageUsingStreaming()
method in jsInterop.js
to pass the image data:
function returnResultsAsString(results) {
let txts = [];
try {
for (let i = 0; i < results.length; ++i) {
txts.push(results[i].barcodeText);
}
let barcoderesults = txts.join(', ');
if (txts.length == 0) {
barcoderesults = 'No barcode found';
}
if (dotnetRef) {
dotnetRef.invokeMethodAsync('ReturnBarcodeResultsAsync', barcoderesults);
}
} catch (e) {
}
}
setImageUsingStreaming: async function setImageUsingStreaming(imageElementId, imageStream) {
const arrayBuffer = await imageStream.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
document.getElementById(imageElementId).src = url;
document.getElementById(imageElementId).style.display = 'block';
if (barcodescanner) {
try {
let results = await barcodescanner.decode(blob);
returnResultsAsString(results);
} catch (ex) {
alert(ex.message);
throw ex;
}
}
},
In the meantime, we invoke the decode()
method to read barcode and QR code from the image buffer and then pass the results to the ReturnBarcodeResultsAsync()
method in BarcodeReader.razor
:
[JSInvokable]
public void ReturnBarcodeResultsAsync(String text)
{
result = text;
StateHasChanged();
}
Now we can test the Blazor WebAssembly app with some barcode and QR code images.
Live Scan Barcode and QR Code Using Camera
In addition to decoding barcode and QR code from static files, we can also do real-time scan with a connected camera.
In the BarcodeReader.razor
file, we add a live scan button:
<button class="btn btn-primary" @onclick="LiveScan">Live Scan</button>
@code {
public async Task LiveScan()
{
await JSRuntime.InvokeVoidAsync(
"jsFunctions.liveScan");
}
}
Then add the corresponding JavaScript function in the jsInterop.js
:
liveScan: async function () {
if (barcodescanner) {
barcodescanner.onFrameRead = async results => {
if (results.length > 0) {
console.log("onFrameRead");
returnResultsAsString(results);
}
};
await barcodescanner.show();
} else {
alert("The barcode reader is still initializing.");
}
},
When we click the button, a popup window that contains a camera preview and camera source list will appear.
Here is the final look of the project:
Source Code
https://github.com/yushulx/blazor-barcode-qrcode-reader-scanner
Top comments (0)