0

テキストから PDF417 バーコードを生成する必要があります。データ、行数、列数を指定してPDF417バーコードを生成するAPI(作成していない)があります(質問に関係のない他のパラメーターの中でも)。

PDF417 バーコードはテキスト エンコーディングを使用しています。これは、1 つのコードワードが最大 2 文字を保持できることを意味します。このバーコードを非常に限られたスペースに印刷しているため、列数を固定する必要があります。

以下は、この文書から私が推測したことです(38 ページ - バーコードのサイジングを参照)。

  1. 行ごとのコードワード数をCWPerRow = 7 とします。
  2. 特定のテキストに必要なコードワードの数、ReqCW = strlen(text) / 2。
  3. 必要な行数 = ReqCW / CWPerRow

上記のアルゴリズムをテストすると、何も表示されません。データが非常に小さく、行数 = 25 のときに同じ API を使用すると、バーコードは問題なく印刷されます (さまざまなバーコード スキャナーで検証済み)。

では、列数がわかっている場合、特定のテキストに必要な行数をどのように計算すればよいでしょうか?

4

2 に答える 2

1

Markus Jarderot の回答の Python ポートを作成しました。計算はそのままです。

import string

SUBMODE_ALPHA = string.ascii_uppercase + ' '
SUBMODE_LOWER = string.ascii_lowercase + ' '
SUBMODE_MIXED = "\t\r #$%&*+,-./0123456789:=^"
SUBMODE_PUNCTUATION = "\t\n\r!\"$'()*,-./:;<>?@[\\]_`{|}~"


def calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, columns):
    rows = ((sourceCodeWords + 1 + errorCorrectionCodeWords) / columns) + 1
    if columns * rows >= sourceCodeWords + 1 + errorCorrectionCodeWords + columns:
        rows -= 1
    return rows

def getErrorCorrectionCodewordCount(errorCorrectionLevel):
    if 0 > errorCorrectionLevel > 8:
        raise ValueError("Error correction level must be between 0 and 8!")
    return 1 << (errorCorrectionLevel + 1)


def calculateSourceCodeWords(msg):
    length = 0;
    submode = SUBMODE_ALPHA
    msgLength = len(msg)
    idx = 0
    while(idx < msgLength):
        ch = msg[idx]
        length += 1

        if not ch in submode:
            old_submode = submode
            if submode == SUBMODE_ALPHA:
                for mode in (SUBMODE_LOWER, SUBMODE_MIXED):
                    if ch in mode:
                        submode = mode

            elif submode == SUBMODE_LOWER:
                if ch in SUBMODE_MIXED:
                    submode = SUBMODE_MIXED

            elif submode == SUBMODE_MIXED:
                for mode in (SUBMODE_ALPHA, SUBMODE_LOWER):
                    if ch in mode:
                        submode = mode

                if idx + 1 < len(msg) and msg[idx + 1] in SUBMODE_PUNCTUATION:
                    submode = SUBMODE_PUNCTUATION


            elif submode == SUBMODE_PUNCTUATION:
                submode = SUBMODE_ALPHA

            if old_submode != submode:
                # submode changed
                continue

            length += 1

        idx += 1 # Don't increment if 'continue' was used.
    return (length + 1) / 2


def main():
    msg = "Hello, world!"
    columns = 7
    sourceCodeWords = calculateSourceCodeWords(msg)
    errorCorrectionCodeWords = getErrorCorrectionCodewordCount(0)
    rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, columns)
    print("\"%s\" requires %d code-words, and %d error correction code-words. This becomes %d rows.\n"
           %( msg, sourceCodeWords, errorCorrectionCodeWords, rows))



if __name__ == '__main__':
    main()
于 2014-08-19T12:11:52.210 に答える