Exemple #1
0
def test_thonky_add_version_info():
    # <http://www.thonky.com/qr-code-tutorial/format-version-information>
    version = 7
    matrix = encoder.make_matrix(version, reserve_regions=False)
    encoder.add_finder_patterns(matrix, is_micro=False)
    encoder.add_alignment_patterns(matrix, version)
    encoder.add_version_info(matrix, version)
    matrix[-8][8] = 0x1  # dark module
    ref_matrix = read_matrix('thonky_version')
    assert ref_matrix == matrix
Exemple #2
0
def test_thonky_add_version_info():
    # <http://www.thonky.com/qr-code-tutorial/format-version-information>
    version = 7
    matrix = encoder.make_matrix(version, reserve_regions=False)
    encoder.add_finder_patterns(matrix, is_micro=False)
    encoder.add_alignment_patterns(matrix, version)
    encoder.add_version_info(matrix, version)
    matrix[-8][8] = 0x1  # dark module
    ref_matrix = read_matrix('thonky_version')
    assert ref_matrix == matrix
Exemple #3
0
def matrix_iter_detail(matrix, version, scale=1, border=None):
    """\
    Returns an iterator / generator over the provided matrix which includes
    the border and the scaling factor.

    This iterator / generator returns different values for dark / light modules
    and therefor the different parts (like the finder patterns, alignment patterns etc.)
    are distinguishable. If this information isn't necessary, use the
    :py:func:`matrix_iter()` function because it is much cheaper and faster.

    If either the `scale` or `border` value is invalid, a py:exc:`ValueError`
    is raised.

    :param matrix: An iterable of bytearrays.
    :param int version: A version constant.
    :param int scale: The scaling factor (default: ``1``).
    :param int border: The border size or ``None`` to specify the
            default quiet zone (4 for QR Codes, 2 for Micro QR Codes).
    :raises: :py:exc:`ValueError` if an illegal scale or border value is provided

    """
    from segno import encoder
    check_valid_border(border)
    scale = int(scale)
    check_valid_scale(scale)
    border = get_border(version, border)
    width, height = get_symbol_size(version, scale=1, border=0)
    is_micro = version < 1
    # Create an empty matrix with invalid 0x2 values
    alignment_matrix = encoder.make_matrix(version, reserve_regions=False, add_timing=False)
    encoder.add_alignment_patterns(alignment_matrix, version)

    def get_bit(i, j):
        # Check if we operate upon the matrix or the "virtual" border
        if 0 <= i < height and 0 <= j < width:
            val = matrix[i][j]
            if not is_micro:
                # Alignment pattern
                alignment_val = alignment_matrix[i][j]
                if alignment_val != 0x2:
                    return (TYPE_ALIGNMENT_PATTERN_LIGHT, TYPE_ALIGNMENT_PATTERN_DARK)[alignment_val]
                if version > 6:  # Version information
                    if i < 6 and width - 12 < j < width - 8 \
                            or height - 12 < i < height - 8 and j < 6:
                        return (TYPE_VERSION_LIGHT, TYPE_VERSION_DARK)[val]
                # Dark module
                if i == height - 8 and j == 8:
                    return TYPE_DARKMODULE
            # Timing - IMPORTANT: Check alignment (see above) in advance!
            if not is_micro and ((i == 6 and j > 7 and j < width - 8) or (j == 6 and i > 7 and i < height - 8)) \
                    or is_micro and (i == 0 and j > 7 or j == 0 and i > 7):
                return (TYPE_TIMING_LIGHT, TYPE_TIMING_DARK)[val]
            # Format - IMPORTANT: Check timing (see above) in advance!
            if i == 8 and (j < 9 or (not is_micro and j > width - 10)) \
                    or j == 8 and (i < 8 or not is_micro and i > height - 9):
                return (TYPE_FORMAT_LIGHT, TYPE_FORMAT_DARK)[val]
            # Finder pattern
            # top left             top right
            if i < 7 and (j < 7 or (not is_micro and j > width - 8)) \
                or not is_micro and i > height - 8 and j < 7:  # bottom left
                return (TYPE_FINDER_PATTERN_LIGHT, TYPE_FINDER_PATTERN_DARK)[val]
            # Separator
            # top left              top right
            if i < 8 and (j < 8 or (not is_micro and j > width - 9)) \
                or not is_micro and (i > height - 9 and j < 8):  # bottom left
                return TYPE_SEPARATOR
            return (TYPE_DATA_LIGHT, TYPE_DATA_DARK)[val]
        else:
            return TYPE_QUIET_ZONE

    for i in range(-border, height + border):
        for s in range(scale):
            yield chain.from_iterable(([get_bit(i, j)] * scale for j in range(-border, width + border)))
Exemple #4
0
def matrix_iter_verbose(matrix, version, scale=1, border=None):
    """\
    Returns an iterator / generator over the provided matrix which includes
    the border and the scaling factor.

    This iterator / generator returns different values for dark / light modules
    and therefor the different parts (like the finder patterns, alignment patterns etc.)
    are distinguishable. If this information isn't necessary, use the
    :py:func:`matrix_iter()` function because it is much cheaper and faster.

    If either the `scale` or `border` value is invalid, a py:exc:`ValueError`
    is raised.

    :param matrix: An iterable of bytearrays.
    :param int version: A version constant.
    :param int scale: The scaling factor (default: ``1``).
    :param int border: The border size or ``None`` to specify the
            default quiet zone (4 for QR Codes, 2 for Micro QR Codes).
    :raises: :py:exc:`ValueError` if an illegal scale or border value is provided
    """
    from segno import encoder
    check_valid_border(border)
    scale = int(scale)
    check_valid_scale(scale)
    border = get_border(version, border)
    width, height = get_symbol_size(version, scale=1, border=0)
    is_micro = version < 1
    # Create an empty matrix with invalid 0x2 values
    alignment_matrix = encoder.make_matrix(version,
                                           reserve_regions=False,
                                           add_timing=False)
    encoder.add_alignment_patterns(alignment_matrix, version)

    def get_bit(i, j):
        # Check if we operate upon the matrix or the "virtual" border
        if 0 <= i < height and 0 <= j < width:
            val = matrix[i][j]
            if not is_micro:
                # Alignment pattern
                alignment_val = alignment_matrix[i][j]
                if alignment_val != 0x2:
                    return (consts.TYPE_ALIGNMENT_PATTERN_LIGHT,
                            consts.TYPE_ALIGNMENT_PATTERN_DARK)[alignment_val]
                if version > 6:  # Version information
                    if i < 6 and width - 12 < j < width - 8 \
                            or height - 12 < i < height - 8 and j < 6:
                        return (consts.TYPE_VERSION_LIGHT,
                                consts.TYPE_VERSION_DARK)[val]
                # Dark module
                if i == height - 8 and j == 8:
                    return consts.TYPE_DARKMODULE
            # Timing - IMPORTANT: Check alignment (see above) in advance!
            if not is_micro and ((i == 6 and 7 < j < width - 8) or (j == 6 and 7 < i < height - 8)) \
                    or is_micro and (i == 0 and j > 7 or j == 0 and i > 7):
                return (consts.TYPE_TIMING_LIGHT, consts.TYPE_TIMING_DARK)[val]
            # Format - IMPORTANT: Check timing (see above) in advance!
            if i == 8 and (j < 9 or (not is_micro and j > width - 10)) \
                    or j == 8 and (i < 8 or not is_micro and i > height - 9):
                return (consts.TYPE_FORMAT_LIGHT, consts.TYPE_FORMAT_DARK)[val]
            # Finder pattern
            # top left             top right
            if i < 7 and (j < 7 or (not is_micro and j > width - 8)) \
                    or not is_micro and i > height - 8 and j < 7:  # bottom left
                return (consts.TYPE_FINDER_PATTERN_LIGHT,
                        consts.TYPE_FINDER_PATTERN_DARK)[val]
            # Separator
            # top left              top right
            if i < 8 and (j < 8 or (not is_micro and j > width - 9)) \
                    or not is_micro and (i > height - 9 and j < 8):  # bottom left
                return consts.TYPE_SEPARATOR
            return (consts.TYPE_DATA_LIGHT, consts.TYPE_DATA_DARK)[val]
        else:
            return consts.TYPE_QUIET_ZONE

    size_range = range(-border, width + border)
    for i in size_range:
        row = tuple(
            chain.from_iterable(
                repeat(get_bit(i, j), scale) for j in size_range))
        for s in repeat(None, scale):
            yield row