alignment-pattern.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /**
  2. * Alignment pattern are fixed reference pattern in defined positions
  3. * in a matrix symbology, which enables the decode software to re-synchronise
  4. * the coordinate mapping of the image modules in the event of moderate amounts
  5. * of distortion of the image.
  6. *
  7. * Alignment patterns are present only in QR Code symbols of version 2 or larger
  8. * and their number depends on the symbol version.
  9. */
  10. var getSymbolSize = require('./utils').getSymbolSize
  11. /**
  12. * Calculate the row/column coordinates of the center module of each alignment pattern
  13. * for the specified QR Code version.
  14. *
  15. * The alignment patterns are positioned symmetrically on either side of the diagonal
  16. * running from the top left corner of the symbol to the bottom right corner.
  17. *
  18. * Since positions are simmetrical only half of the coordinates are returned.
  19. * Each item of the array will represent in turn the x and y coordinate.
  20. * @see {@link getPositions}
  21. *
  22. * @param {Number} version QR Code version
  23. * @return {Array} Array of coordinate
  24. */
  25. exports.getRowColCoords = function getRowColCoords (version) {
  26. if (version === 1) return []
  27. var posCount = Math.floor(version / 7) + 2
  28. var size = getSymbolSize(version)
  29. var intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2
  30. var positions = [size - 7] // Last coord is always (size - 7)
  31. for (var i = 1; i < posCount - 1; i++) {
  32. positions[i] = positions[i - 1] - intervals
  33. }
  34. positions.push(6) // First coord is always 6
  35. return positions.reverse()
  36. }
  37. /**
  38. * Returns an array containing the positions of each alignment pattern.
  39. * Each array's element represent the center point of the pattern as (x, y) coordinates
  40. *
  41. * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}
  42. * and filtering out the items that overlaps with finder pattern
  43. *
  44. * @example
  45. * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.
  46. * The alignment patterns, therefore, are to be centered on (row, column)
  47. * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).
  48. * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns
  49. * and are not therefore used for alignment patterns.
  50. *
  51. * var pos = getPositions(7)
  52. * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]
  53. *
  54. * @param {Number} version QR Code version
  55. * @return {Array} Array of coordinates
  56. */
  57. exports.getPositions = function getPositions (version) {
  58. var coords = []
  59. var pos = exports.getRowColCoords(version)
  60. var posLength = pos.length
  61. for (var i = 0; i < posLength; i++) {
  62. for (var j = 0; j < posLength; j++) {
  63. // Skip if position is occupied by finder patterns
  64. if ((i === 0 && j === 0) || // top-left
  65. (i === 0 && j === posLength - 1) || // bottom-left
  66. (i === posLength - 1 && j === 0)) { // top-right
  67. continue
  68. }
  69. coords.push([pos[i], pos[j]])
  70. }
  71. }
  72. return coords
  73. }