cnf-qrcode
Version:
generate qrcode,support svg base64 utf8
84 lines (73 loc) • 2.95 kB
JavaScript
/**
* Alignment pattern are fixed reference pattern in defined positions
* in a matrix symbology, which enables the decode software to re-synchronise
* the coordinate mapping of the image modules in the event of moderate amounts
* of distortion of the image.
*
* Alignment patterns are present only in QR Code symbols of version 2 or larger
* and their number depends on the symbol version.
*/
import { getSymbolSize } from './utils';
/**
* Calculate the row/column coordinates of the center module of each alignment pattern
* for the specified QR Code version.
*
* The alignment patterns are positioned symmetrically on either side of the diagonal
* running from the top left corner of the symbol to the bottom right corner.
*
* Since positions are simmetrical only half of the coordinates are returned.
* Each item of the array will represent in turn the x and y coordinate.
* @see {@link getPositions}
*
* @param {Number} version QR Code version
* @return {Array} Array of coordinate
*/
export function getRowColCoords(version) {
if (version === 1) return [];
const posCount = Math.floor(version / 7) + 2;
const size = getSymbolSize(version);
const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2;
const positions = [size - 7]; // Last coord is always (size - 7)
for (let i = 1; i < posCount - 1; i++) {
positions[i] = positions[i - 1] - intervals;
}
positions.push(6); // First coord is always 6
return positions.reverse();
};
/**
* Returns an array containing the positions of each alignment pattern.
* Each array's element represent the center point of the pattern as (x, y) coordinates
*
* Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}
* and filtering out the items that overlaps with finder pattern
*
* @example
* For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.
* The alignment patterns, therefore, are to be centered on (row, column)
* positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).
* Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns
* and are not therefore used for alignment patterns.
*
* var pos = getPositions(7)
* // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]
*
* @param {Number} version QR Code version
* @return {Array} Array of coordinates
*/
export function getPositions(version) {
const coords = [];
const pos = getRowColCoords(version);
const posLength = pos.length;
for (let i = 0; i < posLength; i++) {
for (let j = 0; j < posLength; j++) {
// Skip if position is occupied by finder patterns
if ((i === 0 && j === 0) // top-left
|| (i === 0 && j === posLength - 1) // bottom-left
|| (i === posLength - 1 && j === 0)) { // top-right
continue;
}
coords.push([pos[i], pos[j]]);
}
}
return coords;
};