计算QR码对齐模式的位置

时间:2012-11-05 19:09:55

标签: alignment qr-code procedure

我需要知道如何计算the table of ISO/IEC 18004:2000 Annex E中定义的QR码对齐模式的位置。

我不明白它是如何计算的。例如,如果采用版本16,则使用{6,26,50,74}计算位置,并且点之间的距离为{20,24,24}。为什么不是{6,28,52,74},如果点之间的距离{22,24,22}更均匀地分布?

我想知道如何在程序上生成它。

5 个答案:

答案 0 :(得分:4)

虽然规范确实提供了一个对齐表,但这是一个合理的问题(我发现自己的一个:-)) - 在程序上生成位置的可能性有其优点(更少的错字代码,更小的代码足迹,知道位置的模式/属性。)

我很高兴地报告,是的,程序存在(甚至相当简单)。 规范本身就是大部分内容:

  

[对准图案]在时序图案和符号的相对侧之间尽可能均匀地间隔开,在符号内部的定时图案和第一对齐图案之间容纳任何不均匀的间距。

即,仅第一和第二坐标之间的间隔可以与其余间隔不同。其余的必须是平等的。 另一个重要的当然是,为了使AP同意时序模式,间隔必须是均匀的。 剩下的棘手的一点是正确的四舍五入。

无论如何 - 这里的代码打印对齐位置表:

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)))

答案 1 :(得分:1)

对评分最高的答案有一些评论表明它不是100%准确,所以我也在提供我的解决方案。

我的解决方案是用C#编写的。将其翻译成您选择的语言应该很容易。

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's 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;
    }

我得到的值与此处显示的相同:http://www.thonky.com/qr-code-tutorial/alignment-pattern-locations/

总结一下,第一个坐标总是6。

最后一个坐标总是比图像尺寸小7。图像大小计算为4 *版本+17,因此最后一个坐标是4 *版本+10。

如果坐标精确均匀分布,则最后一个坐标的位置将是(first_coordinate +(num-2)* last_coordinate)/(num-1),其中num是所有坐标的数量。 但是坐标的间距不均匀,因此这个位置必须减少到偶数。

其余每个坐标与下一个坐标的距离与下一个坐标的距离相同。

免责声明:我没有阅读任何文档,我只是编写了一些代码,这些代码生成的数字序列与我链接的表格相同。

答案 2 :(得分:0)

我不知道这是否是一个有用的问题。它只是它的方式,如果它是{22,24,22},它并不重要。你问来干什么? 我猜它的间距应该是4个模块的倍数。

答案 3 :(得分:0)

抱歉我的英语。 我希望这可以帮助你,而不是以后回复。 第一件事,标准忘了一件重要的事情就是左上角是用(0,0)定义的。 {6,26,50,74}表示对齐点行坐标和col坐标,我没有 知道为什么他们喜欢这样,也许是为了节省空间。但我们将所有值组合在一起,例如:

{ 6, 26, 50, 74 }

我们得到:

{ 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 }

这些点是对齐图案中心的实际坐标。 Ps:如果一个位置有位置检测模式,我们忽略输出对齐,就像位置一样 (6,6)。

我之前也有这个问题,但现在,我解决了,所以我希望你也能解决它。

祝你好运〜

答案 4 :(得分:0)

这是一个Python解决方案,基本上与@jgosar发布的C#解决方案等效,不同之处在于它纠正了与版本32的thonky.com table的偏差(其他解决方案报告倒数第二个110),而链接表说112):

def get_alignment_positions(version):
    positions = []
    if version > 1:
        n_patterns = version // 7 + 2
        first_pos = 6
        positions.append(first_pos)
        matrix_width = 17 + 4 * version
        last_pos = matrix_width - 1 - first_pos
        second_last_pos = (
            (first_pos + last_pos * (n_patterns - 2)  # Interpolate end points to get point
            + (n_patterns - 1) // 2)                  # Round to nearest int by adding half
                                                      # of divisor before division
            // (n_patterns - 1)                       # Floor-divide by number of intervals
                                                      # to complete interpolation
            ) & -2                                    # Round down to even integer
        pos_step = last_pos - second_last_pos
        second_pos = last_pos - (n_patterns - 2) * pos_step
        positions.extend(range(second_pos, last_pos + 1, pos_step))
    return positions

更正包括首先将倒数第二个位置(向上或向下)舍入到最接近的整数,然后舍入到最接近的偶数整数(而不是直接舍入到最接近的偶数整数)。

免责声明:与@jgosar一样,我不知道thonky.com table是否正确(我不会购买该规范以进行查找)。我已经简单地验证了(通过将表粘贴到上述函数周围的合适包装中),我的解决方案与该表在当前版本中是否匹配。