CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-zxing--library

TypeScript port of ZXing multi-format 1D/2D barcode image processing library

Overview
Eval results
Files

nodejs-integration.mddocs/guides/

Node.js Integration Guide

Guide for using @zxing/library in Node.js environments for server-side barcode processing.

Installation

npm install @zxing/library
# Also install an image processing library
npm install sharp  # Or jimp, canvas, etc.

Using with Sharp

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);

Using with Jimp

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();
}

Batch Processing

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`);

Generating Barcodes

Generate QR Code to File

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');

REST API Example

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'));

Related

  • Quick Start Guide
  • Browser Integration
  • Real-World Scenarios

Install with Tessl CLI

npx tessl i tessl/npm-zxing--library

docs

index.md

tile.json