zoukankan      html  css  js  c++  java
  • 支付宝AR红包引出Python中的PIL小试

    这两天支付宝AR红包火了,周围的同学全在玩。可是我一直在想这个原理是什么?通过请教大神和思考,知道了它有两个限定条件:GPS地理位置和图片的识别。所以,只要我们有了这两个限定条件,就不难进行该红包的破解!

    首先是GPS定位,我们可以采用一个地址模拟器实现,或者就查找本地周围的红包即可。然后关键是图片的识别,刚开始想到的是将提示的图片进行截图,放到电脑上,手机直接扫描截图不就好了?结果是不行的!原因是进行提示的截图中间有若干黑色的条纹,会影响到图片的识别。我们应该怎么处理图片呢?这里提供一种借鉴来的思路:截取每条黑色条纹上面的一小条正常图片,然后填充到黑色条纹上面。效果如下:

    想着最近在学Python,就打算用Python实现,这就需要用到PIL包了。

    一、下载和安装

    Windows下刚开始通过pip install PIL,第一次报错说是pip的版本需要升级,然后按提示升级了pip之后,再运行上述命令,结果运行报错:

    Could not find any downloads that satisfy the requirement PIL

    Some externally hosted files were ignored(use --allow-external PIL to allow)

    于是手动到官网http://www.pythonware.com/products/pil/下载,然后一路next可以解决。

    在Debian/Ubuntu Linux下直接通过apt安装:

    $ sudo apt-get install python-imaging
    

    Mac和其他版本的Linux可以直接使用easy_install或pip安装,安装前需要把编译环境装好:

    $ sudo easy_install PIL
    

    如果安装失败,根据提示先把缺失的包(比如openjpeg)装上。如果失败,有人说可以通过

    pip install PIL --allow-external PIL --allow-unverified PIL

    解决,但是我没有成功。

    要是实在不行,就改用Pillow吧,毕竟PIL从2009年就不更新了。

    二、我的代码

    代码借鉴的大神的,很easy,大概思路就是算出图片的像素,然后算出每条黑色条纹的像素高度,进行截取粘贴即可。大神尝试成功了,可我总是有一些问题,毕竟通过计算像素,误差有点大,效果不是太好。

    # coding=utf-8
    from PIL import Image
    
    image = Image.open("2.png")
    # image.resize((250, 250))
    # image.show()
    image_width = image.size[0]
    image_height = image.size[1]
    
    line_height = 6  # 图片高度
    offset = 3  # 黑色缝隙高度
    for i in range(27):
        img1 = image.crop(
            (0, (line_height + offset) * i, image_width, offset + (line_height + offset) * i))
        # img1 = image.crop((0, 0, image_width, 3))
        image.paste(img1, (0, line_height + (line_height + offset) * i))
    
    image.show()
    print(image_width)
    print(image_height)

    三、PIL一些常见API总结

    打开图片
    1.导入pil的Image模块
    2.使用open(filename)打开文件,返回一个image对象
    Python代码
    im = Image.open('filename')

    此后,一切关于图片的操作均基于这个对象。

    打开后,我们可以查看一些图片信息,如im.format, im.size, im.mode等。调用im.show()会在图片查看工具中显示当前操作的image对象,这个跟个人的系统有关系,我系统中默认是用Windows Picture and Fax Viewer打开的。这个方法用来查看临时的图片效果。

    读写图片
    pil中转换图片格式非常简单(转换图片模式是另一个概念,不要混淆),只需要调用img.save(filename)即可比如有一个bmp(位图)图片,使用img = Image.open('file.bmp')打开后,只需要img.save('file.jpg')即可转换。不过一般情况下,save(filename)是不用做这个用途的,通常,save用以保存一个临时的image对象到硬盘。而转换工作由一个功能更为强大的convert()方法来完成。


    拷贝,粘贴,合并
    Python代码
    box = (100,100,500,500)#设置要拷贝的区域
      
    #将im表示的图片对象拷贝到region中,大小为(400*400)像素。这个region可以用来后续的操作(region其实就是一个Image对象),box变量是一个四元组(左,上,右,下)。
    region = im.crop(box)
      
    region = region.transpose(Image.ROTATE_180)#从字面上就可以看出,先把region中的Image反转180度,然后再放回到region中。
    im.paste(region, box)#粘贴box大小的region到原先的图片对象中。
     
    前面说过,每一个RGB都是由三个通道的灰度图叠加的,所以pil提供了将这三个通道分离的方法
    Python代码
    r,g,b = im.split()#分割成三个通道
    r.show()
    g.show()
    b.show()
    im = Image.merge("RGB", (b, g, r))#将b,r两个通道进行翻转。
     
    几何转变
    几何转变提供resize,rotate等方法,用以重定义图片大小,对图片进行旋转等操作,在实际应用中比较广泛。


    Python代码
    out = img.resize((128, 128))#resize成128*128像素大小。
    out = img.rotate(45)#逆时针旋转45度

    镜面效果,左右翻转
    transpose()方法预定义了一些旋转方式,如
    左右反转,上下翻转,逆时针旋转(90,180,270)度等,非常方便,rotate()和transpose()方法在表现上没有任何不同。

    图片加强

    滤镜
    ImageFilter模块提供了很多预定义的图片加强滤镜。
    比如一个常用的滤镜,细节(detail滤镜)
    Python代码
    import ImageFilter
    out = im.filter(ImageFilter.DETAIL)

    直接操作像素点
    不但可以对每个像素点进行操作,而且,每一个通道都可以独立的进行操作。比如,将每个像素点的亮度(不知道有没有更专业的词)增大20%
    Python代码
    out = img.point(lambda i : i * 1.2)#注意这里用到一个匿名函数(那个可以把i的1.2倍返回的函数)

    对每个点都做20%的增强
     
    如上边的那个例子,我们可以将一个RGB模式的图分离成三个通道的层
    Python代码
    r,g,b = img.split()#神奇而又强大的python语法


    然后对一个通道进行加强或减弱操作,完成后我们又可以使用Merge将通道合并,从而改变图片的色调(冷暖色调的互换)等。

    更高级的图片加强,可以使用ImageEnhance模块,其中包含了大量的预定义的图片加强方式。
    Python代码
    import ImageEnhance
    enh = ImageEnhance.Contrast(im)
    enh.ehhance(1.5).show("50% more contrast")

    读写图片的更多方式
    通常,我们使用open方法进行图片的打开操作。但是这不是唯一的方式。完全可以跟python的IO整合起来。如
    Python代码
    fp = open("file.jpg", "rb")
    im = Image.open(fp)
     
    甚至,你可以从一个字符串中读出图片数据来(python真是神奇啊)。
    Python代码
    import StringIO
    img = Image.open(StringIO.StringIO(buffer))

    四、验证码的识别

    要安装pytesseract库,必须先安装其依赖的PIL及tesseract-ocr,其中PIL为图像处理库,而后面的tesseract-ocr则为google的ocr识别引擎。

    识别代码:

    import pytesseract
    
    from PIL import Image
    
    
    image = Image.open('1.png')
    code = pytesseract.image_to_string(image)
    print (code)
  • 相关阅读:
    U3D开发中关于脚本方面的限制-有关IOS反射和JIT的支持问题
    APP发行渠道
    在WINDOWS上开发IOS应用的方法
    如何安全的在不同工程间安全地迁移asset数据?三种方法
    UNITY 的GC ALLOC到底是什么
    Dictionary,hashtable, stl:map有什么异同?
    如何成为一个优秀的高级C++程序员
    两点间所有路径的遍历算法
    技术人员的未来:做技术还是做管理?
    技术人员如何去面试?
  • 原文地址:https://www.cnblogs.com/DarrenChan/p/6216530.html
Copyright © 2011-2022 走看看