我需要知道如何计算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}更均匀地分布?
我想知道如何在程序上生成它。
答案 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)
{ 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是否正确(我不会购买该规范以进行查找)。我已经简单地验证了(通过将表粘贴到上述函数周围的合适包装中),我的解决方案与该表在当前版本中是否匹配。