[TypeScript][Express][JsBarcode] Generate 1D barcode images
Tags: typescript, express
Published: 2021-10-15 17:44:10

## Intro
This time, I will try generating barcode images by JsBarcode.
Because I want to generate them by Web API, I will use Node.js and Express.js.

* [JsBarcode - Barcode generator written in JavaScript](https://lindell.me/JsBarcode/)

### Environments
* Node.js ver.16.11.0
* TypeScript ver.4.4.4"
* canvas ver.2.8.0
* dpi-tools ver.1.0.7
* Express ver.4.17.1
* jsBarcode ver.3.11.5

## Generate barcode images

I can use jsBarcode in Node.js projects.
To draw barcode images, I have to add node-canvas.

* [Node Setup - Install/JsBarcode Wiki - GitHub](https://github.com/lindell/JsBarcode/wiki/Node-Setup)

#### barcodeGenerator.ts
```ts
import { Canvas } from 'canvas';
import JsBarcode from 'jsbarcode';

function generateBarcode(value: string): Buffer {
    const canvas = new Canvas(100, 100, "image");
    JsBarcode(canvas, value);
    return canvas.toBuffer();
}
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6tmt7a3b95q25wzd0rr.png)

### Options

I can add options.
I can set base options and specific options for specific barcode formats.

For example, "Code39" can choose adding checksum(Modulus43) or not by "mod43".

In TypeScript files, I can't add "mod43" directly.

#### barcodeGenerator.ts
```ts
...
function generateBarcode(value: string): Buffer {
    const canvas = new Canvas(100, 100, "image");
    JsBarcode(canvas, value, {
        // error
        mod43: true,
    });
    return canvas.toBuffer();
}
```

So I create types and add them into options.

#### barcodeGenerator.ts
```ts
...
type Code39Options = {
    format: "CODE39",
    mod43: boolean,
};
function generateBarcode(value: string, options: Code39Options): Buffer {
    const canvas = new Canvas(100, 100, "image");
    JsBarcode(canvas, value, {
        // specific options
        ...options,
        // hide texts what are set under the barcode
        displayValue: false,
        // no white spaces
        margin: 0,
        // Set the width to twice the default
        width: 2,
        height: 100,
        // barcode color
        lineColor: "#000000",
    });
    return canvas.toBuffer();
}
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0vbr6s4rc45ypx018vb.png)

* [Options - Install/JsBarcode Wiki - GitHub](https://github.com/lindell/JsBarcode/wiki/Options)

### DPI

Because jsBarcode uses Canvas to create barcode images, their DPI are 72.
To save as more higher resolution, I use dpi-tools.

* [[TypeScript] Edit images](https://dev.to/masanori_msl/typescript-edit-images-6n4)

```ts
import { Canvas } from 'canvas';
import * as dpiTools from 'dpi-tools';
import JsBarcode from 'jsbarcode';

...
function generateBarcode(value: string, options: Code39Options|Code128Options|CodeItfOptions): Buffer {
    const canvas = new Canvas(100, 100, "image");
    JsBarcode(canvas, value, {
 ...
    });    
    return dpiTools.changeDpiBuffer(canvas.toBuffer(), 600);
}
```

### Image size

As in the sample above, I can set "width" and "height" in the options to change the image sizes.
But "width" unit value isn't inch or milimeter or pixel, and it is effected by the value length.

So when I want to change the image size, I will try do that after creating.

## Get URL queris and create options

In Express projects, I can get URL queries by "req.query".

I can get the URL queries like below.

```json
{
    "value": "0123456789",
    "checksum": true,
}
```

So I get them and parse to create options.

* [Express 4.x - API Reference](https://expressjs.com/en/api.html)

#### index.ts
```ts
import { generateCode39 } from './barcodeGenerator';
import express from 'express';

const port = 3000;
const app = express();

app.get('/code39', (req, res) => {
    const stringifiedQueries = JSON.stringify(req.query);
    const params = getCode39Params(stringifiedQueries);
    res.statusCode = 200;
    res.end(generateCode39(params.value, params.checksum));
});
app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
});
function getCode39Params(stringifiedQueries: string): { readonly value: string, readonly checksum: boolean } {
    const parsedQueries = JSON.parse(stringifiedQueries);
    const value = getQueryText(parsedQueries.value);
    const checksumText = getQueryText(parsedQueries.checksum);
    let checksum = false;
    if(isNullOrEmpty(checksumText) === false) {
        checksum = (checksumText.toLowerCase() === "true");
    }
    return {
        value,
        checksum,
    };
}
function isNullOrEmpty(value: string|undefined|null): boolean {
    if(value == null) {
        return true;
    }
    if(value.length <= 0) {
        return true;
    }
    return false;
}
function getQueryText(value: any): string {
    if(value == null) {
        return "";
    }
    switch(typeof value) {
        case "string":
            return value;
        case "object":
            if(value.length != null &&
                    value.length > 0) {
                return value[0];
            }
            break;
    }
    return "";
}
```

#### barcodeGenerator.ts
```ts
import { Canvas } from 'canvas';
import * as dpiTools from 'dpi-tools';
import JsBarcode from 'jsbarcode';

type Code39Options = {
    format: "CODE39",
    mod43: boolean,
};
export function generateCode39(value: string, checksum: boolean): Buffer {
    return generateBarcode(value.toUpperCase(), {
        format: "CODE39",
        mod43: checksum
    });
}
function generateBarcode(value: string, options: Code39Options): Buffer {
    const canvas = new Canvas(100, 100, "image");
    JsBarcode(canvas, value, {
        ...options,
        displayValue: false,
        margin: 0,
        width: 2,
        height: 100,
        lineColor: "#000000",
    });    
    return dpiTools.changeDpiBuffer(canvas.toBuffer(), 600);
}
```

I also can generate other barcode types like "Code128", "ITF", and etc.

I also want to try generating 2D barcode images.