Code前端首页关于Code前端联系我们

Python 图像处理库 pillow,提取支付宝和微信支付图片二维码

terry 2年前 (2023-09-25) 阅读数 49 #后端开发
Python图像处理库pillow,提取支付宝和微信支付图像的二维码,提取中间部分我们可以使用图像处理软件,但是图像处理软件不利于批量处理,而且学习也需要一定的成本。本文将教你如何使用Python的图像处理库Cushion轻松批量提取图像中间的方形二维码部分。

提取思路

以微信支付收款码图片为例:

分析图片,我们可以看到二维码是白底的,白底是绿底的。我们以图像的左上角为坐标原点,水平方向为X轴(向右为正方向),垂直方向为Y轴(向下方向为正方向)。我们的目标是确定白色背景的 4 个角的坐标。

从图像左侧中间水平向右交叉。当背景颜色由绿色变为白色时,该点的横坐标为左上角和左下角的横坐标,记为x_left。

同样,从图像右侧的中心向左侧交叉。当背景颜色由绿色变为白色时,该点的横坐标为右上角和右下角的横坐标,记为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_顶部+h)。

代码实现

有了上面的思路我们就可以编写Python脚本了。代码中给出了详细的注释。基本思想是导入图像并将其转换为二维矩阵。矩阵的元素是图像中对应像素的RGBA值,然后根据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。请参见使用说明的自述文件。脚本源代码仓库:clip-pay-pic

作者:追梦者
链接:https://juejin.im/post/5c655d60f265da2de04aa2a9
来源:掘金,版权归作者所有。如需商业转载,请联系求作者授权。非商业转载请来源。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门