Python批量提取支付宝和微信支付二维码区域的方法
本文介绍使用Python的Pillow库批量提取支付宝和微信支付收款二维码的方法。通过分析图片颜色变化确定白色背景区域的坐标,自动裁剪出方形二维码部分,避免手动使用图片处理软件,提高批量处理效率。
支付宝或微信支付导出的收款二维码图片,通常包含二维码图案以及大面积的背景装饰图案。例如,微信支付的收款二维码就具有这种特征。

若仅需提取图片中央的方形二维码区域,使用图片处理软件虽可行,但不利于批量操作且存在学习成本。本文将演示如何利用Python的图像处理库Pillow,实现二维码区域的批量自动提取。
提取思路
以微信支付收款码图片为例进行分析。
观察图片结构可知,二维码位于白色背景区域内,而白色背景又置于绿色背景之上。建立坐标系:以图片左上角为原点,水平向右为x轴正方向,垂直向下为y轴正方向。核心目标是确定白色背景区域四个顶点的坐标。
从图片左侧中点水平向右扫描,当背景颜色由绿色变为白色时,该点的横坐标即为左上角和左下角的横坐标,记为x_left。
同理,从图片右侧中点水平向左扫描,当背景颜色由绿色变为白色时,该点的横坐标即为右上角和右下角的横坐标,记为x_right。
白色背景的宽度(及高度,因二维码区域为正方形)h可通过公式计算: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+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,具体使用方法请参考README文档。仓库地址:clip-pay-pic
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









