Calculating the position of QR code alignment patterns

I need to know how to calculate the positions of QR code alignment patterns as defined in table ISO / IEC 18004: 2000 Appendix E.

I do not understand how it is calculated. For example, if you take version 16, the positions are calculated using {6,26,50,74}, and the distance between the points is {20,24,24}. Why is it not {6,28,52,74} if the distances between the points {22,24,22} are distributed more evenly?

I would like to know how this can be created procedurally.

+4
source share
4 answers

While the specification provides an alignment table, this is a reasonable question (and one I found myself with :-)) - the ability to generate positions procedurally has its merits (less sealed code, less trace code, knowledge of the pattern / properties of positions).

I am pleased to report that yes, there is a procedure (and it is quite simple). The specification itself says this:

[Alignment patterns] are arranged as evenly as possible between the synchronization pattern and the opposite side of the symbol, with an uneven distance between the synchronization pattern and the first alignment pattern in the interior of the symbol.

That is, only the interval between the first and second coordinates can differ from other intervals. The rest should be equal. Another important bit, of course, is that to match the access points with the synchronization patterns, the intervals must be even. The remaining hard bit is just rounding.

In any case, here the code prints a table of alignment positions:

def size_for_version(version): return 17 + 4 * version def alignment_coord_list(version): if version == 1: return [] divs = 2 + version // 7 size = size_for_version(version) total_dist = size - 7 - 6 divisor = 2 * (divs - 1) # Step must be even, for alignment patterns to agree with timing patterns step = (total_dist + divisor // 2 + 1) // divisor * 2 # Get the rounding right coords = [6] for i in range(divs - 2, -1, -1): # divs-2 down to 0, inclusive coords.append(size - 7 - i * step) return coords for version in range(1, 40 + 1): # 1 to 40 inclusive print("V%d: %s" % (version, alignment_coord_list(version))) 
+4
source

There are a few comments on the top rated answer that suggest it is not 100% accurate, so I also make my decision.

My solution is written in C #. It should be easy to translate into the language of your choice.

 private static int[] getAlignmentCoords(int version) { if (version <= 1) { return new int[0]; } int num = (version / 7) + 2;//number of coordinates to return int[] result = new int[num]; result[0] = 6; if (num == 1) { return result; } result[num - 1] = 4 * version + 10; if (num == 2) { return result; } result[num - 2] = 2 * ((result[0] + result[num - 1] * (num - 2)) / ((num - 1) * 2)); //leave these brackets alone, because of integer division they ensure you get a number that divisible by 2 if (num == 3) { return result; } int step = result[num - 1] - result[num - 2]; for (int i = num - 3; i > 0; i--) { result[i] = result[i + 1] - step; } return result; } 

The values ​​I get are the same as shown here: http://www.thonky.com/qr-code-tutorial/alignment-pattern-locations/

To summarize, the first coordinate is always 6.

The last coordinate is always 7 smaller than the image size. Image size is calculated as 4 * version + 17, so the last coordinate is 4 * version + 10.

If the coordinates were exactly evenly distributed, the position of one coordinate before the last would be (first_coordinate + (num-2) * last_coordinate) / (num-1), where num is the number of all coordinates. But the coordinates are not evenly distributed, so this position should be reduced to an even number.

Each of the remaining coordinates is at the same distance from the next, since the last two are from each other.

Disclaimer: I have not read any documentation, I just wrote code that generates a sequence of numbers, the same as in the table associated with.

+1
source

I do not know if this is a useful question. So it is, and it does not really matter if it were {22,24,22}. Why do you ask? I assume the interval should be a multiple of 4 modules.

0
source

Sorry for my English. Hope this helps you, not later. firstly, the standard forgets that the upper left is determined using (0,0). {6, 26, 50, 74} means the coordinate of the row of alignment points and the coordinate of the column, and I don’t know why they do this, possibly to save space. but we combine all the values, for example:

 { 6, 26, 50, 74 } 

and get:

 { 6 , 6 } ---> ( the x coordinate is 6, and the y is 6, from top/left ) { 6 , 26 } { 6 , 50 } { 6 , 74 } { 26, 26 } { 26, 50 } { 26, 74 } { 50, 50 } { 50, 74 } { 74, 74 } 

These points are the actual coordinate of the center of the alignment patterns. Ps: if the position has position detection patterns, we ignore the alignment of the output, for example, position (6, 6).

I also have this question before, but now I am solving it, so I hope you can solve it too.

good luck ~

0
source

Source: https://habr.com/ru/post/980170/


All Articles