Skip to content
This repository has been archived by the owner on Apr 15, 2024. It is now read-only.

Commit

Permalink
comments, code style, doc (#6)
Browse files Browse the repository at this point in the history
Co-authored-by: Jakub Havelka <[email protected]>
  • Loading branch information
landsman and HamAndRock authored Mar 8, 2022
1 parent b21a34b commit 0d10f19
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 80 deletions.
9 changes: 9 additions & 0 deletions .docs/arm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Using package on ARM processors

This example is for Macbook Pro M1.

## Steps

1. [Install tooling for Rosseta](https://support.apple.com/en-gb/HT211861)
2. [Open iTerm / Terminal with Rosseta](https://apple.stackexchange.com/a/428769)
3. Run package and projects depending on that from this terminal
57 changes: 57 additions & 0 deletions .docs/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Examples

## Quick Example

```js
import { generateQRWithImage } from '@trisbee/qr-image-nodejs';

const imageBuffer;

// for option values please visit https://www.npmjs.com/package/qrcode#qr-code-options library
const options = {
errorCorrectionLevel: 'Q',
color: {
dark: '#0CC8A8'
}
};

// This will create QR with 'https://trisbee.com' encoded in it and with centered image also color will be #0CC8A8
const resultWithImage = generateQRWithImage('https://trisbee.com', 500, 100, imageBuffer, options);

// This will create just QR code with 'https://trisbee.com' encoded in it in color #0CC8A8
const resultWithoutImage = generateQRWithImage('https://trisbee.com', 500, 100, null, options);

// This will create classic B&W QR code with 'https://trisbee.com' encoded in it
const resultWithoutImageAndOptions = generateQRWithImage('https://trisbee.com', 500, 100, null, null);

// The buffer of outputed QR code
const imageBuffer = resultWithImage.buffer;
const imageInBase64 = resultWithImage.buffer.toString('base64');

// The precentage of how much the inserted image area of QR code image covers
// if 'errorCorrectionLevel' is not specified theoretical maxium of how much the image can cover is 30%
// but we recommend to keep it under 20 and make sure the image doesn't touch the big rectangles in the corners
// of QR
const imageQRCoverage = resultWithImage.coverage;
```


## Express example

```ts
import express = require('express');
import { generateQRWithImage } from '@trisbee/qr-image-nodejs';

const app = express();
app.use(express.json());
app.listen(3000);

// When opening http://localhost:300/generateQR?content=trisbee.com the browser should render QR code of size 200 px
// and with margin of 100px
app.get('/generateQr', async (req, res) => {
const data = await generateQRWithImage(req.params.content, 200, 100);

res.contentType('image/png');
res.end(data.buffer);
});
```
9 changes: 9 additions & 0 deletions .docs/typings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Typings

```ts
generateQRWithImage(qrCodeContent: string, width: number, margin: number, imageBuffer?: Buffer, options?: QRCodeToBufferOptions)
```

## Options

For options please visit documentation of [qrcode](https://www.npmjs.com/package/qrcode#qr-code-options) library.
67 changes: 6 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,21 @@
# QR Image

Simple library allowing you to generate an image in middle of an QR code or without it.

This library contains only 1 method and that is `generateQRWithImage` and uses libraries
[qrcode](https://www.npmjs.com/package/qrcode) and [canvas](https://www.npmjs.com/package/canvas) to generate the
resulting image.

### Quick Example

```js

import { generateQRWithImage } from '@trisbee/qr-image-nodejs';

const imageBuffer;

// for option values please visit https://www.npmjs.com/package/qrcode#qr-code-options library
const options = {
errorCorrectionLevel: 'Q',
color: {
dark: '#0CC8A8'
}
};


// This will create QR with 'https://trisbee.com' encoded in it and with centered image also color will be #0CC8A8
const resultWithImage = generateQRWithImage('https://trisbee.com', 500, 100, imageBuffer, options)
// This will create just QR code with 'https://trisbee.com' encoded in it in color #0CC8A8
const resultWithoutImage = generateQRWithImage('https://trisbee.com', 500, 100, null, options)
// This will create classic B&W QR code with 'https://trisbee.com' encoded in it
const resultWithoutImageAndOptions = generateQRWithImage('https://trisbee.com', 500, 100, null, null)

// The buffer of outputed QR code
const imageBuffer = resultWithImage.buffer;
const imageInBase64 = resultWithImage.buffer.toString('base64')

// The precentage of how much the inserted image area of QR code image covers
// if 'errorCorrectionLevel' is not specified theoretical maxium of how much the image can cover is 30%
// but we recommend to keep it under 20 and make sure the image doesn't touch the big rectangles in the corners
// of QR
const imageQRCoverage = resultWithImage.coverage



```


### Express example
```ts
import express = require('express');
import { generateQRWithImage } from '@trisbee/qr-image-nodejs';

const app = express();
app.use(express.json());
app.listen(3000);
## Documentation

// When opening http://localhost:300/generateQR?content=trisbee.com the browser should render QR code of size 200 px
// and with margin of 100px
app.get('/generateQr', async (req, res) => {
const data = await generateQRWithImage(req.params.content, 200, 100)
- [Examples](.docs/examples.md)
- [Typings](.docs/typings.md)

res.contentType('image/png')
res.end(data.buffer)
})
## How to start

- [Using on ARM CPUs like M1](.docs/arm.md)

```


### Typings
```ts
generateQRWithImage(qrCodeContent: string, width: number, margin: number, imageBuffer?: Buffer, options?: QRCodeToBufferOptions)
```

### Options

For options please visit documentation of [qrcode](https://www.npmjs.com/package/qrcode#qr-code-options) library
59 changes: 40 additions & 19 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,78 @@
import QRCOde = require('qrcode');
import {QRCodeToBufferOptions} from "qrcode";


const {createCanvas, loadImage} = require('canvas')
import {createCanvas, loadImage} from "canvas";

interface QRResponse {
buffer: Buffer,
coverage: number
}


export const generateQRWithImage = async (qrCodeContent: string, width: number, margin: number, imageBuffer?: Buffer | null, options?: QRCodeToBufferOptions): Promise<QRResponse> => {

const fullHeight = width + margin;

const canvas = createCanvas(fullHeight, fullHeight)
const ctx = canvas.getContext('2d')
/**
* Print QR code with image inside (logo of the company)
*
* @param qrCodeContent string, for example URL address
* @param width in px
* @param margin in px
* @param imageBuffer image that you want to place inside the QR code
* @param options QR code options for dependency "qrcode" - https://www.npmjs.com/package/qrcode#qr-code-options
*/
export async function generateQRWithImage(
qrCodeContent: string,
width: number,
margin: number,
imageBuffer?: Buffer | null,
options?: QRCodeToBufferOptions
): Promise<QRResponse> {

/** we want's to create a square, so this is size of one of the side */
const squareSideSize = width + margin;

/** init new canvas */
const canvas = createCanvas(squareSideSize, squareSideSize);

/** create context for drawing on canvas */
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, fullHeight, fullHeight);
ctx.fillRect(0, 0, squareSideSize, squareSideSize);

if (options) {
options.width = width;
options.margin = 0;
}


/** Returns a Buffer containing a representation of the QR Code image. Only works with png format */
const qrBuffer = await QRCOde.toBuffer(qrCodeContent, options || {
errorCorrectionLevel: imageBuffer ? 'H' : 'M',
width: width,
margin: 0,
})

ctx.drawImage(await loadImage(qrBuffer), margin / 2, margin / 2)
/** put prepared QR code to the canvas */
ctx.drawImage(await loadImage(qrBuffer), margin / 2, margin / 2);

/** volume of image in pixels */
let imageVolume = 0;

/** if we want to put image inside the QR code we will draw it above it, to middle of the square */
if (imageBuffer) {
let image = await loadImage(imageBuffer);
imageVolume = image.width * image.height
imageVolume = image.width * image.height;

/** calculates the center point of the image in QR */
let dx = (width / 2 - image.width / 2) + margin / 2;
ctx.drawImage(image, dx, dx)
}

/** draw our image above the QR code */
ctx.drawImage(image, dx, dx);
}

/** calculates the final volume of image in pixels (x * y) */
const qrVolume = width * width;
const result = (imageVolume / qrVolume) * 100;

/** calculates how much volume of the qr code is covered by the image in % */
const result = (imageVolume / qrVolume) * 100;

return {
buffer: canvas.toBuffer(),
coverage: result,
}


}

0 comments on commit 0d10f19

Please sign in to comment.