Created
January 6, 2022 14:09
-
-
Save maxammann/2e1c616d17800eeb045488efd7932e46 to your computer and use it in GitHub Desktop.
Generate QR-codes and embed them in PDFs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.0/jspdf.umd.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/@zxing/library@0.18.6/umd/index.min.js"></script> | |
</head> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { | |
jsPDF | |
} = window.jspdf; | |
const { | |
EncodeHintType, | |
IllegalStateException, | |
QRCodeDecoderErrorCorrectionLevel, | |
QRCodeEncoder, | |
QRCodeEncoderQRCode | |
} = window.ZXing; | |
const QRCode = QRCodeEncoderQRCode | |
const ErrorCorrectionLevel = QRCodeDecoderErrorCorrectionLevel | |
const DEFAULT_QUIET_ZONE_SIZE = 10 | |
// Adapted from https://github.com/zxing-js/library/blob/d1a270cb8ef3c4dba72966845991f5c876338aac/src/browser/BrowserQRCodeSvgWriter.ts#L91 | |
const createQRCode = (text, | |
renderRect, | |
renderBoundary, | |
size, hints) => { | |
let errorCorrectionLevel = ErrorCorrectionLevel.L; | |
let quietZone = DEFAULT_QUIET_ZONE_SIZE; | |
const { | |
width, | |
height | |
} = { | |
width: size, | |
height: size | |
} | |
if (hints) { | |
if (hints.get(EncodeHintType.ERROR_CORRECTION)) { | |
errorCorrectionLevel = ErrorCorrectionLevel.fromString(hints.get(EncodeHintType.ERROR_CORRECTION).toString()); | |
} | |
if (hints.get(EncodeHintType.MARGIN) !== undefined) { | |
quietZone = Number.parseInt(hints.get(EncodeHintType.MARGIN).toString(), 10); | |
} | |
} | |
const code = QRCodeEncoder.encode(text, errorCorrectionLevel, hints); | |
const input = code.getMatrix(); | |
if (input === null) { | |
throw new IllegalStateException(); | |
} | |
const inputWidth = input.getWidth(); | |
const inputHeight = input.getHeight(); | |
const qrWidth = inputWidth + (quietZone * 2); | |
const qrHeight = inputHeight + (quietZone * 2); | |
const outputWidth = Math.max(width, qrWidth); | |
const outputHeight = Math.max(height, qrHeight); | |
const multiple = Math.min(Math.floor(outputWidth / qrWidth), Math.floor(outputHeight / qrHeight)); | |
// Padding includes both the quiet zone and the extra white pixels to accommodate the requested | |
// dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone. | |
// If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will | |
// handle all the padding from 100x100 (the actual QR) up to 200x160. | |
const leftPadding = Math.floor((outputWidth - (inputWidth * multiple)) / 2); | |
const topPadding = Math.floor((outputHeight - (inputHeight * multiple)) / 2); | |
renderBoundary(0, 0, outputWidth, outputHeight) | |
for (let inputY = 0; inputY < inputHeight; inputY++) { | |
// Write the contents of this row of the barcode | |
for (let inputX = 0; inputX < inputWidth; inputX++) { | |
if (input.get(inputX, inputY) === 1) { | |
let outputX = leftPadding + inputX * multiple; | |
let outputY = topPadding + inputY * multiple; | |
renderRect(outputX, outputY, multiple) | |
} | |
} | |
} | |
} | |
const drawjsPDF = (text, x, y, size, pdfDocument, border = true, version = 7) => { | |
const hints = new Map() | |
hints.set(EncodeHintType.MARGIN, 0) | |
hints.set(EncodeHintType.QR_VERSION, version) | |
createQRCode(text, (rectX, rectY, rectSize) => { | |
pdfDocument.rect(x + rectX, y + rectY, rectSize, rectSize, "FD"); | |
}, | |
(rectX, rectY, rectWidth, rectHeight) => { | |
if (border) { | |
pdfDocument.setLineWidth(.4) | |
pdfDocument.roundedRect(x + rectX, y + rectY, rectWidth, rectHeight, 10, 10, "D"); | |
pdfDocument.setLineWidth(0) | |
} | |
}, size, hints) | |
} | |
var doc = new jsPDF(); | |
drawjsPDF("test", 0, 0, 100, doc) | |
doc.save('Test.pdf'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment