Python извлекает платежный QR-код Alipay и WeChat

Python

Эта статья была впервые опубликована в моем личном блоге. Дополнительные руководства по разработке Python и django можно найти на страницеБлог Ловца снов.

В дополнение к части QR-кода в QR-коде коллекции, экспортируемом Alipay или WeChat Pay, есть большой фоновый узор.Например, ниже приведен QR-код коллекции WeChat Pay:

Иногда нам нужна только квадратная часть QR-кода в середине изображения.Чтобы извлечь среднюю часть, мы можем использовать программное обеспечение для обработки изображений, но программное обеспечение для обработки изображений не способствует пакетной обработке, а обучение также требует определенных затрат. Эта статья научит вас использовать подушку библиотеки обработки изображений Python для простого пакетного извлечения квадратной части QR-кода в середине изображения.

Извлечение идей

В качестве примера возьмем изображение кода сбора платежей WeChat:

Анализируя изображение, мы видим, что QR-код находится на белом фоне, который, в свою очередь, на зеленом фоне. Возьмем левый верхний угол изображения за начало координат, горизонтальная ось — это ось абсцисс (правое направление — положительное направление), а вертикальное направление — ось у (направление вниз — положительное направление). направление). Наша цель — определить координаты 4-х углов белой части фона.

Крест по горизонтали от середины вправо левой стороны изображения.При изменении цвета фона с зеленого на белый абсциссой положения точки является абсцисса левого верхнего угла и левого нижнего угла, обозначаемая как х_левый.

Аналогично, пересечь горизонтально из середины правой части картинки влево.При изменении цвета фона с зеленого на белый абсцисса положения точки является абсциссой правого верхнего угла и правого нижнего угла, обозначается как x_right.

Тогда белая ширина и высота предпосылки h = x_right - x_left.

Затем вверх (или вниз, например, до здесь), начиная с точки, когда зеленый фон на белом фоне, когда цвет фона от белого до зеленого и вертикальной оси - это положение точка, где верхняя левая и правая ордината, упоминается как y_top.

Тогда ординаты нижнего левого и нижнего правого углов можно рассчитать как (y_top + h).

Таким образом, определяются координаты четырех углов белой фоновой части соответственно (по часовой стрелке от левого верхнего угла): (x_left, y_top), (x_right, y_top), (x_right, y_top+h), (x_left, y_top+ час).

Код

С приведенными выше идеями мы можем легко писать сценарии Python. Подробные комментарии приведены в коде.Основная идея состоит в том, чтобы импортировать картинку и преобразовать ее в двумерную матрицу.Элементами матрицы являются значения RGBA соответствующих пикселей картинки, а затем определить -be-to-be на основе изменения значения RGBA (т.е. изменения цвета) Просто обрежьте границу.

import glob
from PIL import Image

if __name__ == '__main__':
    filenames = glob.glob('*.png')  # 微信支付收款码导出为 png 格式
    filenames.extend(glob.glob('*.jpg'))  # 支付宝收款码导出为 jpg 格式

    for filename in filenames:
        with Image.open(filename) as img:
            img.convert('RGBA')
            pix_data = img.load()

            # 图片左上角为原点,横向为 x 轴(向右为正方向),纵向为 y 轴(向下为正方向)
            width, height = img.size  # 图片宽和高
            mid_height = height // 2  # 图片正中纵坐标

            # 确定左边界横坐标:
            x_left = 0
            for x in range(width):
                rgba = pix_data[x, mid_height]
                if rgba[:3] == (255, 255, 255):
                    x_left = x
                    break

            # 确定右边界横坐标:
            x_right = width - 1  # 右边界
            for x in range(width - 1, 0, -1):
                rgba = pix_data[x, mid_height]
                if rgba[:3] == (255, 255, 255):
                    x_right = x
                    break

            h = x_right - x_left  # 白色背景高度(正方形)
            mid_height_rgba = pix_data[x_left, mid_height]
            if filename.endswith('png'):
                # 微信支付往下确定下边界纵坐标,因为当设置了收款金额时,金额显示在上方
                y_bottom = mid_height
                for y in range(mid_height, height):
                    rgba = pix_data[x_left, y]
                    if rgba != mid_height_rgba:
                        y_bottom = y
                        break
                box = (x_left, y_bottom - h, x_right, y_bottom)
            else:
                # 支付宝往上确定上边界纵坐标,因为当设置了收款金额时,金额显示在下方
                y_top = mid_height
                for y in range(mid_height, 0, -1):
                    rgba = pix_data[x_left, y]
                    if rgba != mid_height_rgba:
                        y_top = y
                        break
                box = (x_left, y_top, x_right, y_top + h)
            crop = img.crop(box) # box 参数为四元组,分别为左上角和右下角的横纵坐标
            crop.save('./result/{}'.format(filename))

Код скрипта загружается на GitHub в то же время, пожалуйста, обратитесь к документу README для использования. Репозиторий исходников скриптов:clip-pay-pic

Мой публичный аккаунт для обмена идеями по программированию и учебными материалами, пожалуйста, обратите внимание:Пончик программиста