In a PDF417 barcode where number of columns are fixed, how would I calculate the number of rows required for some text?

后端 未结 2 777
天命终不由人
天命终不由人 2021-01-16 18:59

I need to generate a PDF417 barcode from some text. I have an API (that I didn\'t create) that generates a PDF417 barcode given the data, number of rows and number of column

2条回答
  •  无人及你
    2021-01-16 19:21

    I've made a Python port of Markus Jarderot's answer. The calculation remains the same.

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

提交回复
热议问题