Python提取支付宝和微信支付二维码的示例代码


Posted in Python onFebruary 15, 2019

支付宝或者微信支付导出的收款二维码,除了二维码部分,还有很大一块背景图案,例如下面就是微信支付的收款二维码:

Python提取支付宝和微信支付二维码的示例代码

有时候我们仅仅只想要图片中间的方形二维码部分,为了提取出中间部分,我们可以使用图片处理软件,但图片处理软件不利于批处理,且学习也需要一定成本。本文将教你使用 Python 的图像处理库 pillow,轻松批量提取图片中间的方形二维码部分。

提取思路

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

分析图片我们可以看到,二维码位于白色背景中,而白色背景又位于绿色背景上。我们以图片左上角为坐标原点,横向为 x 轴(向右为正方向),纵向为 y 轴(向下为正方向)。我们的目标是需要确定白色背景部分 4 个角的坐标。

从图片左边正中向右横向穿过,当背景色从绿色变为白色时,该点所在位置的横坐标即为左上角和左下角的横坐标,记为 x_left。

同理从图片右边正中向左横向穿过,当背景色从绿色变为白色时,该点所在位置的横坐标即为右上角和右下角的横坐标,记为 x_right。

则白色背景宽度和高度为 h = x_right - x_left。

再从绿色背景转为白色背景时的点向上(或者向下,此处以向上为例)出发,当背景色从白色又变为绿色时,该点所在位置的纵坐标即为左上角和右上角的纵坐标,记为 y_top。

则可以计算出左下角和右下角的纵坐标为 (y_top + h)。

由此,白色背景部分 4 个角的坐标均确定,分别为(从左上角开始顺时针):(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

Python 相关文章推荐
Python中方法链的使用方法
Feb 23 Python
python 中random模块的常用方法总结
Jul 08 Python
CentOS 7 安装python3.7.1的方法及注意事项
Nov 01 Python
python的pstuil模块使用方法总结
Jul 26 Python
python实现邮件自动发送
Aug 10 Python
Django获取应用下的所有models的例子
Aug 30 Python
python爬虫爬取幽默笑话网站
Oct 24 Python
关于Numpy中的行向量和列向量详解
Nov 30 Python
Python Django中的STATIC_URL 设置和使用方式
Mar 27 Python
Django DRF APIView源码运行流程详解
Aug 17 Python
浅析Python中字符串的intern机制
Oct 03 Python
matplotlib事件处理基础(事件绑定、事件属性)
Feb 03 Python
Python实现的IP端口扫描工具类示例
Feb 15 #Python
Python标准库使用OrderedDict类的实例讲解
Feb 14 #Python
Python从文件中读取数据的方法讲解
Feb 14 #Python
python爬取cnvd漏洞库信息的实例
Feb 14 #Python
基于python历史天气采集的分析
Feb 14 #Python
Python 实现域名解析为ip的方法
Feb 14 #Python
解决python Markdown模块乱码的问题
Feb 14 #Python
You might like
php 去除html标记--strip_tags与htmlspecialchars的区别详解
2013/06/26 PHP
如何取得中文字符串中出现次数最多的子串
2013/08/08 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
ThinkPHP开发--使用七牛云储存
2017/09/14 PHP
PHP 获取 ping 时间的实现方法
2017/09/29 PHP
JQuery对checkbox操作 (循环获取)
2011/05/20 Javascript
JS保留小数点(四舍五入、四舍六入)实现思路及实例
2013/04/25 Javascript
jquery退出each循环的写法
2014/02/26 Javascript
封装好的javascript前端分页插件pagination
2016/01/04 Javascript
js实现上传图片及时预览
2016/05/07 Javascript
Javascript小技能总结(推荐)
2016/06/02 Javascript
JS实现的表头列头固定页面功能示例
2017/01/10 Javascript
解决iView中时间控件选择的时间总是少一天的问题
2018/03/15 Javascript
vue组件化中slot的基本使用方法
2019/05/01 Javascript
vue-cli+axios实现文件上传下载功能(下载接收后台返回文件流)
2019/05/10 Javascript
vue-cli3配置与跨域处理方法
2019/08/17 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
2020/10/28 Javascript
[38:23]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第一场
2014/05/24 DOTA
python使用wxPython打开并播放wav文件的方法
2015/04/24 Python
Python中DJANGO简单测试实例
2015/05/11 Python
Python变量赋值的秘密分享
2018/04/03 Python
实例讲解Python脚本成为Windows中运行的exe文件
2019/01/24 Python
python多线程http压力测试脚本
2019/06/25 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
2020/09/23 Python
阳光体育:Sunny Sports(购买露营和远足设备)
2018/08/07 全球购物
校企合作协议书
2014/04/16 职场文书
工作求职自荐信
2014/06/13 职场文书
2014年小学语文工作总结
2014/12/20 职场文书
2014年度考核工作总结
2014/12/24 职场文书
2015幼儿园新学期寄语
2015/02/27 职场文书
员工自我工作评价
2015/03/06 职场文书
婚礼迎宾词大全
2015/08/10 职场文书
学生会干部任命书
2015/09/21 职场文书
高二英语教学反思
2016/03/03 职场文书