Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sec-ant/zxing-wasm
ZXing-C++ WebAssembly as an ES/CJS module with types. Read/Write barcodes in web, node, bun and deno.
https://github.com/sec-ant/zxing-wasm
barcode bun deno esmodule node qrcode typescript wasm web webassembly zxing zxing-cpp
Last synced: 22 days ago
JSON representation
ZXing-C++ WebAssembly as an ES/CJS module with types. Read/Write barcodes in web, node, bun and deno.
- Host: GitHub
- URL: https://github.com/sec-ant/zxing-wasm
- Owner: Sec-ant
- License: mit
- Created: 2023-04-03T12:15:28.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-13T10:35:45.000Z (23 days ago)
- Last Synced: 2024-10-14T03:02:43.851Z (22 days ago)
- Topics: barcode, bun, deno, esmodule, node, qrcode, typescript, wasm, web, webassembly, zxing, zxing-cpp
- Language: TypeScript
- Homepage: https://zxing-wasm.deno.dev
- Size: 717 KB
- Stars: 79
- Watchers: 0
- Forks: 8
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# zxing-wasm
[![npm](https://img.shields.io/npm/v/zxing-wasm)](https://www.npmjs.com/package/zxing-wasm/v/latest) [![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/zxing-wasm)](https://www.npmjs.com/package/zxing-wasm/v/latest) [![jsDelivr hits (npm scoped)](https://img.shields.io/jsdelivr/npm/hm/zxing-wasm?color=%23ff5627)](https://cdn.jsdelivr.net/npm/zxing-wasm@latest/) [![deploy status](https://github.com/Sec-ant/zxing-wasm/actions/workflows/deploy.yml/badge.svg)](https://github.com/Sec-ant/zxing-wasm/actions/workflows/deploy.yml)
[ZXing-C++](https://github.com/zxing-cpp/zxing-cpp) WebAssembly as an ES/CJS module with types. Read or write barcodes in various JS runtimes: web, node, bun and deno.
Visit [this online demo](https://zxing-wasm-demo.deno.dev/) to quickly explore its basic functions. It works best on the latest chromium browsers.
## Build
```bash
git clone --recurse-submodules https://github.com/Sec-ant/zxing-wasm
cd zxing-wasm
# install pnpm first:
# https://pnpm.io/installation
pnpm i --frozen-lockfile
# install cmake first:
# https://cmake.org/download/
pnpm cmake
# install emscripten first:
# https://emscripten.org/docs/getting_started/downloads.html
pnpm build:wasm
pnpm build
```## Install
```
npm i zxing-wasm
```## Documentation
https://zxing-wasm.deno.dev/
## Demo
Demo page: https://zxing-wasm-demo.deno.dev/
Demo source: https://github.com/Sec-ant/zxing-wasm-demo
## Usage
This package exports 3 subpaths: `full`, `reader` and `writer`. You can choose whichever fits your needs. If you use TypeScript, you should set [`moduleResolution`](https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution) to [`bundler`](https://www.typescriptlang.org/docs/handbook/modules/reference.html#bundler), [`node16` or `nodenext`](https://www.typescriptlang.org/docs/handbook/modules/reference.html#node16-nodenext-1) in your `tsconfig.json` file to properly resolve the exported module.
### `zxing-wasm` or `zxing-wasm/full`
These 2 subpaths include functions to both read and write barcodes. The wasm binary size is ~1.19 MB.
```ts
import {
readBarcodesFromImageFile,
readBarcodesFromImageData,
writeBarcodeToImageFile,
} from "zxing-wasm";
```or
```ts
import {
readBarcodesFromImageFile,
readBarcodesFromImageData,
writeBarcodeToImageFile,
} from "zxing-wasm/full";
```### `zxing-wasm/reader`
This subpath only includes functions to read barcodes. The wasm binary size is ~917 KB.
```ts
import {
readBarcodesFromImageFile,
readBarcodesFromImageData,
} from "zxing-wasm/reader";
```### `zxing-wasm/writer`
This subpath only includes a function to write barcodes. The wasm binary size is ~366 KB.
```ts
import { writeBarcodeToImageFile } from "zxing-wasm/writer";
```### IIFE Scripts
Apart from ES and CJS modules, this package also ships IIFE scripts. The registered global variable is named `ZXingWASM`.
```html
```
### [`readBarcodesFromImageFile`](https://zxing-wasm.deno.dev/functions/full.readBarcodesFromImageFile.html) and [`readBarcodesFromImageData`](https://zxing-wasm.deno.dev/functions/full.readBarcodesFromImageData.html)
These 2 functions are for reading barcodes.
[`readBarcodesFromImageFile`](https://zxing-wasm.deno.dev/functions/full.readBarcodesFromImageFile.html) accepts an image [`Blob`](https://developer.mozilla.org/docs/Web/API/Blob) or an image [`File`](https://developer.mozilla.org/docs/Web/API/File) as the first input. They're encoded images, e.g. `.png` `.jpg` files.
[`readBarcodesFromImageData`](https://zxing-wasm.deno.dev/functions/full.readBarcodesFromImageData.html) accepts an [`ImageData`](https://developer.mozilla.org/docs/Web/API/ImageData) as the first input. They're raw pixels that usually acquired from [``](https://developer.mozilla.org/docs/Web/HTML/Element/canvas) or related APIs.
Both of these 2 functions optionally accept the same second input: [`ReaderOptions`](https://zxing-wasm.deno.dev/interfaces/full.ReaderOptions.html).
The return result of these 2 functions is a `Promise` of an array of [`ReadResult`](https://zxing-wasm.deno.dev/interfaces/full.ReadResult.html)s.
e.g.
```ts
import {
readBarcodesFromImageFile,
readBarcodesFromImageData,
type ReaderOptions,
} from "zxing-wasm/reader";const readerOptions: ReaderOptions = {
tryHarder: true,
formats: ["QRCode"],
maxNumberOfSymbols: 1,
};/**
* Read from image file/blob
*/
const imageFile = await fetch(
"https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=Hello%20world!",
).then((resp) => resp.blob());const imageFileReadResults = await readBarcodesFromImageFile(
imageFile,
readerOptions,
);console.log(imageFileReadResults[0].text); // Hello world!
/**
* Read from image data
*/
const imageData = await createImageBitmap(imageFile).then((imageBitmap) => {
const { width, height } = imageBitmap;
const context = new OffscreenCanvas(width, height).getContext(
"2d",
) as OffscreenCanvasRenderingContext2D;
context.drawImage(imageBitmap, 0, 0, width, height);
return context.getImageData(0, 0, width, height);
});const imageDataReadResults = await readBarcodesFromImageData(
imageData,
readerOptions,
);console.log(imageDataReadResults[0].text); // Hello world!
```### [`writeBarcodeToImageFile`](https://zxing-wasm.deno.dev/functions/full.writeBarcodeToImageFile.html)
This function is used to write barcodes. The first argument of this function is a text string to be encoded and the optional second argument is an [`WriterOptions`](https://zxing-wasm.deno.dev/interfaces/full.WriterOptions.html).
The return result of this function is a `Promise` of a [`WriteResult`](https://zxing-wasm.deno.dev/interfaces/full.WriteResult.html).
e.g.
```ts
import { writeBarcodeToImageFile, type WriterOptions } from "zxing-wasm/writer";const writerOptions: WriterOptions = {
format: "QRCode",
width: 150,
height: 150,
margin: 10,
eccLevel: 2,
};const writeOutput = await writeBarcodeToImageFile(
"Hello world!",
writerOptions,
);console.log(writeOutput.image);
```## Notes
When using this package, the `.wasm` binary needs to be served along with the JS glue code. In order to provide a smooth dev experience, the serve path is automatically assigned the [jsDelivr CDN](https://fastly.jsdelivr.net/npm/zxing-wasm/) url upon build.
If you would like to change the serve path (to one of your local network hosts, some other CDNs, or just Base64 encoded data URIs), please use [`setZXingModuleOverrides`](https://zxing-wasm.deno.dev/functions/full.setZXingModuleOverrides.html) to override the [`locateFile`](https://emscripten.org/docs/api_reference/module.html?highlight=locatefile#Module.locateFile) function in advance. `locateFile` is one of the [Emscripten `Module` attribute hooks](https://emscripten.org/docs/api_reference/module.html?highlight=locatefile#affecting-execution) that can affect the code execution of the `Module` object during its lifecycles.
e.g.
```ts
import { setZXingModuleOverrides, writeBarcodeToImageFile } from "zxing-wasm";// override the locateFile function
setZXingModuleOverrides({
locateFile: (path, prefix) => {
if (path.endsWith(".wasm")) {
return `https://unpkg.com/zxing-wasm@1/dist/full/${path}`;
}
return prefix + path;
},
});// call read or write functions afterwards
const writeOutput = await writeBarcodeToImageFile("Hello world!");
```The wasm binary won't be fetched or instantiated unless a [read](#readbarcodesfromimagefile-and-readbarcodesfromimagedata) or [write](#writebarcodetoimagefile) function is firstly called, and will only be instantiated once given the same ([`Object.is`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/is)) [ZXingModuleOverrides](https://zxing-wasm.deno.dev/types/full.ZXingModuleOverrides). If you want to manually trigger the download and instantiation of the wasm binary prior to any read or write functions, you can use [`getZXingModule`](https://zxing-wasm.deno.dev/functions/full.getZXingModule). This function will also return a `Promise` that resolves to a [`ZXingModule`](https://zxing-wasm.deno.dev/types/full.ZXingModule).
```ts
import { getZXingModule } from "zxing-wasm";/**
* This function will trigger the download and
* instantiation of the wasm binary immediately
*/
const zxingModulePromise1 = getZXingModule();const zxingModulePromise2 = getZXingModule();
console.log(zxingModulePromise1 === zxingModulePromise2); // true
```[`getZXingModule`](https://zxing-wasm.deno.dev/functions/full.getZXingModule) can also optionally accept a [`ZXingModuleOverrides`](https://zxing-wasm.deno.dev/types/full.ZXingModuleOverrides.html) argument.
```ts
import { getZXingModule } from "zxing-wasm";getZXingModule({
locateFile: (path, prefix) => {
if (path.endsWith(".wasm")) {
return `https://unpkg.com/zxing-wasm@1/dist/full/${path}`;
}
return prefix + path;
},
});
```## License
MIT