python-qrcodeのマスク処理結果の評価方法が若干間違っている
lincolnloop/python-qrcode: Python QR Code image generator
このライブラリはマスク処理結果の評価方法が若干仕様と異なっているため、他のライブラリとはできあがったQRコードが違う結果になることがある。 間違っているのはQRコードの仕様書の次の部分。
1:1:3:1:1 比率パターンの前又は後ろに比率4の幅以上の明パターンが存在する。 qrcode_specification_ja
python-qrcodeの該当部分は下記になるが、1:1:3:1:1 比率パターンの出現自体を評価してしまっている。 本来は1:1:3:1:1 比率パターンの前か後ろに比率4の幅以上の明パターンが存在することを評価すべきである。
def _lost_point_level3(modules, modules_count): modules_range_short = xrange(modules_count-6) lost_point = 0 for row in xrange(modules_count): this_row = modules[row] for col in modules_range_short: if (this_row[col] and not this_row[col + 1] and this_row[col + 2] and this_row[col + 3] and this_row[col + 4] and not this_row[col + 5] and this_row[col + 6]): lost_point += 40 for col in xrange(modules_count): for row in modules_range_short: if (modules[row][col] and not modules[row + 1][col] and modules[row + 2][col] and modules[row + 3][col] and modules[row + 4][col] and not modules[row + 5][col] and modules[row + 6][col]): lost_point += 40 return lost_point
skip2/go-qrcode: QR Code encoder (Go)
では、下記のようになっており、1:1:3:1:1 比率パターンの出現だけではなく、その前後に比率4の幅以上の明パターンが存在するかどうかまできちんと評価している。
func (m *symbol) penalty3() int { penalty := 0 for y := 0; y < m.symbolSize; y++ { var bitBuffer int16 = 0x00 for x := 0; x < m.symbolSize; x++ { bitBuffer <<= 1 if v := m.get(x, y); v { bitBuffer |= 1 } switch bitBuffer & 0x7ff { // 0b000 0101 1101 or 0b10111010000 // 0x05d or 0x5d0 case 0x05d, 0x5d0: penalty += penaltyWeight3 bitBuffer = 0xFF default: if x == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d { penalty += penaltyWeight3 bitBuffer = 0xFF } } } } for x := 0; x < m.symbolSize; x++ { var bitBuffer int16 = 0x00 for y := 0; y < m.symbolSize; y++ { bitBuffer <<= 1 if v := m.get(x, y); v { bitBuffer |= 1 } switch bitBuffer & 0x7ff { // 0b000 0101 1101 or 0b10111010000 // 0x05d or 0x5d0 case 0x05d, 0x5d0: penalty += penaltyWeight3 bitBuffer = 0xFF default: if y == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d { penalty += penaltyWeight3 bitBuffer = 0xFF } } } } return penalty }
しかし、適用されるマスクパターンが間違っているぐらいではQRコードが読めなかったりはしないので実用上は問題なかったりする。 (読みにくくなったりするケースはあれど)
追記 2017/03/31
この件を修正するPull Requestが送られているようだ。