A lightweight and zero-dependencies pure Node.js barcode generator.
Table of Contents
Presentation
Bitgener is a barcode generator written in pure Node.js using ES6 and ES7 features. It is based on the great work made by Jean-Baptiste Demonte and contributors: barcode.
Despite the fact that bwipjs can generate a lot of barcodes and other libraries exist, I personally needed to generate the same ECC 200 compliant Datamatrixes from the barcode library and it was not possible by any of these libraries. Plus I had some issues with architecture-dependent image processor libraries used by other modules.
Bitgener generates barcodes in pure SVG (Scalable Vector Graphics) format. The barcode generated can be a buffer, a readable stream, a string representing SVG tags content or a file. It adds features like background and bars opacity, fixing final image width and height, keeping the original 1D/2D size, adding paddings and a generic font family for hri, adding stream, buffer and file outputs with a specific encoding.
SVGs generated by Bitgener uses crisp edges shape rendering to tell the user agent to turn off anti-aliasing to preserved the contrast, colors and edges without any smoothing or blurring that applies to images scaled up or down. Browsers support is nice and can be found here: https://caniuse.com/#feat=css-crisp-edges.
The aim of this project is to provide a simple, lightweight, zero-dependencies and fast barcode generator and let user choose the external or native image processing library to transform the SVG generated into the specific format if needed.
Bitgener Online Demo
Show me!
Installation
npm install bitgener
npm i -S bitgener
Technical information
Node.js
- Language: JavaScript ES6/ES7
- VM: Node.js >=10.0.0
Debugging
- Own debugger embedded that writes on process.stderr when the DEBUG environment variable is set. See Environment variables.
Tests
Linting
ESLint with Airbnb base rules. See Airbnb JavaScript Style Guide.
npm run lint
Unit
Mocha and Chai.
npm test
Supported symbologies
One dimension:
- Codabar
- Code 11
- Code 39
- Code 93
- Code 128
- Ean 8
- Ean 13
- Standard 2 of 5
- Interleaved 2 of 5
- MSI
- UPC
Two dimensions:
- DataMatrix (ECC 200 standard, square and rectangular)
Usage
Library
Import Bitgener
Bitgener module exports one async function named bitgener.
const bitgener = require('bitgener');
bitgener(options): AsyncFunction
-
options
<Object>:
data
* <String> The data to encode.type
* <String> The supported symbology in which data will be encoded.
codabar
: each character to encode must be one of 0123456789-$:/.+code11
: each character to encode must be one of 0123456789-code39
: each character to encode must be one of 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%code93
: each character to encode must be one of 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%code128
: each character to encode must be one of !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ean8
: data to encode must contain 7 numerical digits.ean13
: data to encode must contain 12 numerical digits.std25
(standard 2 of 5): data to encode must contain only numerical digits.int25
(interleaved 2 of 5): data to encode must contain only numerical digits.msi
: data to encode must contain only numerical digits.upc
: data to encode must contain 11 numerical digits.datamatrix
: data to encode has no restrictions.
output
<String> The output format for the svg property of the object returned by this function. Default: stream
stream
: generated SVG tags as a Readable Stream.string
: generated SVG tags as a string.buffer
: generated SVG tags as a Buffer.{path to a file}
: a valid path to a SVG file. The file will be created or overwritten, eg.: './docs/bitgener.svg'.
encoding
<String> For stream, buffer and file outputs. Default: utf8
utf8
: multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.ascii
: for 7-bit ASCII data only. This encoding is fast and will strip the high bit if set.utf16le
: 2 or 4 bytes, little-endian encoded Unicode characters. Surrogate pairs (U+10000 to U+10FFFF) are supported.ucs2
: alias of 'utf16le'.base64
: base64 encoding. When creating a Buffer from a string, this encoding will also correctly accept "URL and Filename Safe Alphabet" as specified in RFC4648, Section 5.latin1
: a way of encoding the Buffer into a one-byte encoded string (as defined by the IANA in RFC1345, page 63, to be the Latin-1 supplement block and C0/C1 control codes).binary
: alias for 'latin1'.hex
: encode each byte as two hexadecimal characters.
crc
<Boolean> Cyclic redundancy check. For code93, std25, int25 and msi barcode types. Default: true
rectangular
<Boolean> For datamatrix only. Default: false
padding
<Number> The space in pixels around one side of the barcode that will be applied for its 4 sides. Default: 0
width
<Number> The width in pixels to fix for the generated image. Default: 150
height
<Number> The height in pixels to fix for the generated image. Default: 150
barWidth
<Number> The bar width in pixels for 1D barcodes. Default: 1
barHeight
<Number> The bar height in pixels for 1D barcodes. Default: 50
original1DSize
<Boolean> If true keep the original 1D barcode size determined by barWidth and barHeight else apply the specified width and height sizes to the final image. Default: false
original2DSize
<Boolean> For rectangular datamatrixes, if true keep the original 2D barcode size based on width else apply the specified width and height sizes to the final image. Default: false
addQuietZone
<Boolean> Add a quiet zone at the end of 1D barcodes. Default: true
color
<String> The bars and hri color. An hexadecimal value or one of these generic names. Default: #000000
opacity
<Number> The bars and hri opacity. Min: 0
Max: 1
Default: 1
bgColor
<String> The background color. An hexadecimal value or one of these generic names. Default: #FFFFFF
bgOpacity
<Number> The background opacity. Min: 0
Max: 1
Default: 1
hri
<Object> The human readable interpretation of the encoded data.
show
<Boolean> Default: true
fontFamily
<String> A generic font name based on cssfontstack.com Default: Arial
Sans-serif
Arial
Arial Black
Arial Narrow
Arial Rounded MT Bold
Avant Garde
Calibri
Candara
Century Gothic
Franklin Gothic Medium
Futura
Geneva
Gill Sans
Helvetica
Impact
Lucida Grande
Optima
Segoe UI
Tahoma
Trebuchet MS
Verdana
Serif
Bodoni MT
Book Antiqua
Calisto MT
Cambria
Didot
Garamond
Goudy Old Style
Lucida Bright
Palatino
Perpetua
Rockwell
Rockwell Extra Bold
Baskerville
Times New Roman
Consolas
Courier New
Lucida Console
Lucida Sans Typewriter
Monaco
Andale Mono
Copperlate
Papyrus
Brush Script MT
fontSize
<Number> The font size in pixels. Default: 10
marginTop
<Number> The margin size in pixels between the barcode bottom and the hri text. Default: 0
-
Returns: <Promise>
- Resolve: <Object>
width
<Number> The final image width.height
<Number> The final image height.density
<Number> The number of pixels per inch (DPI) calculated as optimized.type
<String> The symbology used.data
<String> The data encoded.hri
<String> The human readable interpretation of the encoded data.output
<String> The effective output option used.encoding
<String> The encoding format used.svg
<Readable> | <String> | <Buffer> The SVG tags of the generated SVG image. In case the ouput is a file, this field contains the SVG tags in a string format.
- Throws: <DataError> | <BarcodeTypeError> | <OutputError>
Examples
You can find these examples here: docs/examples
In these examples please prefer a well-known and tested asynchronous logger over the use of console module.
1D barcode
const bitgener = require('bitgener');
(async () => {
try {
const ret = await bitgener({
data: '012345',
type: 'code93',
output: 'buffer',
encoding: 'utf8',
crc: false,
padding: 25,
barWidth: 5,
barHeight: 150,
original1DSize: true,
addQuietZone: true,
color: '#FFFFFF',
opacity: 1,
bgColor: '#F7931A',
bgOpacity: 0.1,
hri: {
show: true,
fontFamily: 'Futura',
fontSize: 25,
marginTop: 9,
},
});
console.log(ret);
} catch (e) {
console.error(e.toString());
}
})();
2D barcode
const bitgener = require('bitgener');
(async () => {
try {
const ret = await bitgener({
data: 'Bitgener',
type: 'datamatrix',
output: 'bitgener.svg',
encoding: 'utf8',
rectangular: true,
padding: 0,
width: 250,
height: 250,
original2DSize: false,
color: '#FFFFFF',
opacity: 1,
bgColor: '#F7931A',
bgOpacity: 1,
hri: {
show: true,
fontFamily: 'Courier New',
fontSize: 15,
marginTop: 0,
},
});
console.log(ret);
} catch (e) {
console.error(e.toString());
}
})();
Full example using Sharp
const stream = require('stream');
const { createWriteStream } = require('fs');
const path = require('path');
const { promisify } = require('util');
const sharp = require('sharp');
const bitgener = require('bitgener');
const pipeline = promisify(stream.pipeline);
const convert = async function convert({
buffer,
density,
format,
method,
filePath,
} = {}) {
const sharped = sharp(buffer, { density });
let ret;
if (method === 'toFile' || filePath !== undefined) {
ret = await sharped.toFile(filePath);
} else if (method === 'toBuffer') {
ret = sharped.toFormat(format).toBuffer();
} else {
ret = sharped[format]();
}
return ret;
};
(async () => {
try {
const wstream = createWriteStream(path.join(__dirname, 'sharped.png'));
const {
svg: buffer,
density,
} = await bitgener({
data: 'Bitgener',
type: 'datamatrix',
output: 'buffer',
encoding: 'utf8',
rectangular: true,
padding: 0,
width: 250,
height: 250,
original2DSize: false,
color: '#FFFFFF',
opacity: 1,
bgColor: '#F7931A',
bgOpacity: 1,
hri: {
show: true,
fontFamily: 'Courier New',
fontSize: 15,
marginTop: 0,
},
});
const rstream = await convert({
buffer,
density,
format: 'png',
});
await pipeline(rstream, wstream);
} catch (e) {
console.error(e.toString());
}
})();
Environment variables
DEBUG is used to whether debug a specific module. DEBUG value can be a comma-separated string listing module names to debug or to avoid debugging. Format is: DEBUG=moduleName[,moduleName]
DEBUG=moduleName
will debug moduleName module;DEBUG=moduleName:*
will debug moduleName module and sub modules;DEBUG=-moduleName:*
will disable debugging any moduleName module and sub modules;DEBUG=*
will debug all moduleName module and sub modules plus other modules used in your project if they use a debugger similar to bugbug embed in this module.
Example: DEBUG=bitgener:*
Errors
Object structure
Errors emitted by Bitgener inherit the native Error prototype with an additional code
property and toString
method.
{
name,
code,
message,
stack,
toString(),
}
Codes
name | code | description | module |
---|
DataError |
MISSING_DATA | The data to encode is missing. | src/index |
EMPTY_DATA | The data to encode is empty. | src/index |
INVALID_DATA | The data to encode doesn't require the prerequisites. | src/index src/Barcode/ |
BarcodeTypeError |
MISSING_BARCODE_TYPE | The symbology supported is missing. | src/index |
INVALID_BARCODE_TYPE | The symbology is not one of those supported. | src/index |
OutputError |
INVALID_OUTPUT | The output is not one of those supported. If the ouput is a path to a file make sure that the path is valid. | src/helpers/output |
BarcodeError |
NO_DIGIT | The barcode generator returned no digit and cannot generate svg tags. | src/Barcode/index |
ReadableStreamError |
READABLE_INTERNAL | Internal failure or invalid chunk of data pushed on readable stream. | src/helpers/output |
WritableStreamError |
WRITABLE_INTERNAL | Internal failure writing or piping data on writable stream. | src/helpers/output |
LibError |
UNKNOWN_ERROR | An unknown error was caught by the library. | - |
Code of Conduct
This project has a Code of Conduct. By interacting with this repository, organization, or community you agree to abide by its terms.
Contributing
Please have a look at our TODO for any work in progress.
Please take also a moment to read our Contributing Guidelines if you haven't yet done so.
Support
Please see our Support page if you have any questions or for any help needed.
Security
For any security concerns or issues, please visit our Security Policy page.
License
MIT.