TypeScript port of ZXing multi-format 1D/2D barcode image processing library
Guide for using @zxing/library in Node.js environments for server-side barcode processing.
npm install @zxing/library
# Also install an image processing library
npm install sharp # Or jimp, canvas, etc.import {
MultiFormatReader,
BinaryBitmap,
HybridBinarizer,
RGBLuminanceSource
} from '@zxing/library';
import sharp from 'sharp';
async function decodeFromFile(filePath: string): Promise<string> {
// Load image and convert to raw pixels
const { data, info } = await sharp(filePath)
.raw()
.toBuffer({ resolveWithObject: true });
// Create luminance source
const luminanceSource = new RGBLuminanceSource(
new Uint8ClampedArray(data),
info.width,
info.height
);
// Decode
const binaryBitmap = new BinaryBitmap(new HybridBinarizer(luminanceSource));
const reader = new MultiFormatReader();
const result = reader.decode(binaryBitmap);
return result.getText();
}
// Usage
const text = await decodeFromFile('./barcode.png');
console.log('Decoded:', text);import {
MultiFormatReader,
BinaryBitmap,
HybridBinarizer,
RGBLuminanceSource
} from '@zxing/library';
import Jimp from 'jimp';
async function decodeWithJimp(filePath: string): Promise<string> {
const image = await Jimp.read(filePath);
// Convert to grayscale
image.grayscale();
const luminanceSource = new RGBLuminanceSource(
new Uint8ClampedArray(image.bitmap.data),
image.bitmap.width,
image.bitmap.height
);
const binaryBitmap = new BinaryBitmap(new HybridBinarizer(luminanceSource));
const reader = new MultiFormatReader();
const result = reader.decode(binaryBitmap);
return result.getText();
}import { promises as fs } from 'fs';
import path from 'path';
async function processBarcodeDirectory(dirPath: string): Promise<Map<string, string>> {
const files = await fs.readdir(dirPath);
const results = new Map<string, string>();
const reader = new MultiFormatReader();
const hints = new Map();
hints.set(DecodeHintType.TRY_HARDER, true);
reader.setHints(hints);
for (const file of files) {
if (!file.match(/\.(png|jpg|jpeg)$/i)) continue;
const filePath = path.join(dirPath, file);
try {
const text = await decodeFromFile(filePath);
results.set(file, text);
console.log(`${file}: ${text}`);
} catch (error) {
console.error(`${file}: Failed to decode`);
}
}
return results;
}
// Usage
const results = await processBarcodeDirectory('./barcodes');
console.log(`Processed ${results.size} barcodes`);import {
QRCodeWriter,
BarcodeFormat,
EncodeHintType,
QRCodeDecoderErrorCorrectionLevel
} from '@zxing/library';
import sharp from 'sharp';
async function generateQRCodeFile(
text: string,
outputPath: string,
size: number = 300
): Promise<void> {
const writer = new QRCodeWriter();
const hints = new Map();
hints.set(EncodeHintType.ERROR_CORRECTION, QRCodeDecoderErrorCorrectionLevel.H);
hints.set(EncodeHintType.MARGIN, 2);
const bitMatrix = writer.encode(text, BarcodeFormat.QR_CODE, size, size, hints);
// Convert BitMatrix to image buffer
const buffer = Buffer.alloc(bitMatrix.getWidth() * bitMatrix.getHeight());
for (let y = 0; y < bitMatrix.getHeight(); y++) {
for (let x = 0; x < bitMatrix.getWidth(); x++) {
const offset = y * bitMatrix.getWidth() + x;
buffer[offset] = bitMatrix.get(x, y) ? 0 : 255;
}
}
// Save as PNG
await sharp(buffer, {
raw: {
width: bitMatrix.getWidth(),
height: bitMatrix.getHeight(),
channels: 1
}
})
.png()
.toFile(outputPath);
}
// Usage
await generateQRCodeFile('https://example.com', './qrcode.png');import express from 'express';
import multer from 'multer';
import {
MultiFormatReader,
QRCodeWriter,
BarcodeFormat,
BinaryBitmap,
HybridBinarizer,
RGBLuminanceSource
} from '@zxing/library';
import sharp from 'sharp';
const app = express();
const upload = multer({ storage: multer.memoryStorage() });
// Decode endpoint
app.post('/decode', upload.single('image'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No image provided' });
}
try {
const { data, info } = await sharp(req.file.buffer)
.raw()
.toBuffer({ resolveWithObject: true });
const luminanceSource = new RGBLuminanceSource(
new Uint8ClampedArray(data),
info.width,
info.height
);
const bitmap = new BinaryBitmap(new HybridBinarizer(luminanceSource));
const reader = new MultiFormatReader();
const result = reader.decode(bitmap);
res.json({
text: result.getText(),
format: result.getBarcodeFormat()
});
} catch (error) {
res.status(400).json({ error: 'No barcode found' });
}
});
// Generate endpoint
app.post('/generate', async (req, res) => {
const { text, format = 'QR_CODE', size = 300 } = req.body;
if (!text) {
return res.status(400).json({ error: 'Text required' });
}
try {
const writer = new QRCodeWriter();
const bitMatrix = writer.encode(text, BarcodeFormat.QR_CODE, size, size);
// Convert to PNG buffer
const buffer = Buffer.alloc(bitMatrix.getWidth() * bitMatrix.getHeight());
for (let y = 0; y < bitMatrix.getHeight(); y++) {
for (let x = 0; x < bitMatrix.getWidth(); x++) {
buffer[y * bitMatrix.getWidth() + x] = bitMatrix.get(x, y) ? 0 : 255;
}
}
const pngBuffer = await sharp(buffer, {
raw: {
width: bitMatrix.getWidth(),
height: bitMatrix.getHeight(),
channels: 1
}
}).png().toBuffer();
res.type('image/png').send(pngBuffer);
} catch (error) {
res.status(500).json({ error: 'Generation failed' });
}
});
app.listen(3000, () => console.log('Server running on port 3000'));Install with Tessl CLI
npx tessl i tessl/npm-zxing--library@0.21.14