【Python 滑块不同的操作】对滑块进行处理,列如切割、还原、去除、无脑识别距离等等

news2024/9/28 19:18:58

文章日期:2024.03.23

使用工具:Python

类型:图片滑块验证的处理(不限于识别距离)

使用场景:?

文章全程已做去敏处理!!!  【需要做的可联系我】

AES解密处理(直接解密即可)(crypto-js.js 标准算法):在线AES加解密工具

今天的这个案例的主要作用是方便大家对滑块的研究、使用、学习、原理理解等..... 

源码在文章结尾,源码有详细注释,有任何问题直接私信!!!     持续更新中........

目录

1、极验3.0滑块 【还原】【距离计算】- 还原滑块背景图,并计算出缺口距离

2、极验4.0滑块 【转换】- 小拼图转长拼图

3、简书滑块 【切割】- 切割出仅有缺口的滑道

4、网易易盾滑块 【转换】- 长拼图转小拼图

5、极验4.0滑块 【去除】- 拼图去除半透明像素

【附上源码-python】- 持续更新


使用场景:

1、极验3.0滑块 【还原】【距离计算】- 还原滑块背景图,并计算出缺口距离

需要材料:完整滑块背景图(图片)、有缺口的滑块背景图(图片)

# 还原 完整滑块背景图  将还原后的结果保存为名字为:a1   默认会自动添加文件后缀名png
Slide_processing().background_reduction('1.jpg',True,'a1')
# 还原 有缺口的滑块背景图  将还原后的结果保存为名字为:a2   默认会自动添加文件后缀名png
Slide_processing().background_reduction('2.jpg',True,'a2')
# 放入 【完整滑块背景图】 和 【有缺口的滑块背景图】 计算缺口的距离  strict:容错值,默认为0
print(Slide_processing().slider_identify_background('a1.png','a2.png',strict=200))

2、极验4.0滑块 【转换】- 小拼图转长拼图

需要材料:小拼图(图片)、背景图的总高度(数字距离)、服务器返回的拼图放置高度(数字距离)

 

'''
:param p_puzzle_path:  本地小拼图的的路径
:param total_height:  背景图图片的总高度 - 上下距离 - 最终拼图的高度 - 要和滑块的背景图的高度一致
:param starting_height:  拼图图片的放置位置,从上倒下计算距离,设置20则表示从上到下,距离20个像素点开始放置拼图 - 通常服务器会返回此参数
:param save_file:  是否保存最终修改后的图片  默认False不保存 
:param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成 (使用此参数请先开启save_file)
:return: base64图片
'''
print(Slide_processing().slider_puzzle_big(p_puzzle_path='a1.png',
                                           total_height=200,
                                           starting_height=95,
                                           save_file=True,
                                           save_file_path='q1'))

3、简书滑块 【切割】- 切割出仅有缺口的滑道

需要材料:有缺口的滑块背景图(图片)、长拼图(图片)

# 将正常大拼图转换为小拼图 - 放置长拼图 - 文章下面有此函数的详细讲解
G = Slide_processing().slider_puzzle_qg('a2.png')
print(G)
'''
:param b_puzzle_path:  本地滑块背景图的路径
:param b_size_h:  小拼图在背景图中的所在高度,上下距离
:param p_size_h:  小拼图的高度大小
:param save_file:  是否保存最终修改后的图片 默认False
:param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
:return: base64图片
'''
print(Slide_processing().background_cutting(b_puzzle_path='a1.png',
                                            b_size_h=G['最顶层-顶层距离'],
                                            p_size_h=G['中间层-拼图的高度'],
                                            save_file=True,
                                            save_file_path='s1'))

4、网易易盾滑块 【转换】- 长拼图转小拼图

需要材料:长拼图(图片)

# 将正常大拼图转换为小拼图 - 放置长拼图
'''
:param p_puzzle_path:  本地长拼图的路径
:param save_file:  是否保存最终修改后的图片 默认False
:param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
:return: {
            '最顶层-顶层距离'
            '中间层-拼图的高度'
            '最底层-底层距离'
            'base64'
        }
'''
G = Slide_processing().slider_puzzle_qg(p_puzzle_path='a1.png',
                                        save_file=True,
                                        save_file_path='s1')
print(G)

5、极验4.0滑块 【去除】- 拼图去除半透明像素

需要材料:拼图(图片)

'''
:param p_puzzle_path:  本地小拼图的路径
:param save_file:  是否保存最终修改后的图片 默认False
:param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
:return: base64图片
'''
print(Slide_processing().slider_puzzle_remove_tm(p_puzzle_path='a1.png',
                                                 save_file=True,
                                                 save_file_path='s1'))

【附上源码-python】- 持续更新

import numpy as np
from PIL import Image
import io
import time
import base64

class Slide_processing:
    def __init__(self):
        pass


    # 将小拼图转为正常大拼图
    def slider_puzzle_big(self,
                          p_puzzle_path: str = '',
                          total_height: int = 300,
                          starting_height: int = 50,
                          save_file: bool = False,
                          save_file_path: str = ''
                          ):
        '''
        :param p_puzzle_path:  本地小拼图的的路径
        :param total_height:  设置图片总高度 - 上下距离 - 最终拼图的高度 - 要和滑块的背景图的高度一致
        :param starting_height:  设置拼图图片的放置位置,从上倒下计算距离,设置20则表示从上到下,距离20个像素点开始放置拼图
        :param save_file:  是否保存最终修改后的图片 默认False
        :param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
        :return: base64图片
        '''
        # 打开小拼图图片
        image = Image.open(p_puzzle_path)
        # 获取图片的宽高
        width, height = image.size
        # 获取图片的像素数据
        pixels = image.load()

        # 创建空白图片 - 高:自定义  宽:拼图的宽度  颜色:透明  格式:png
        new_image = Image.new('RGBA', (width, total_height), color=(0, 0, 0, 0))

        # 开始循环读取拼图的每一个像素值,然后放到空白图片中
        # 循环读取拼图的高度(上下距离)
        for x in range(height):
            # 循环读取拼图的宽度(左右距离)
            for y in range(width):
                # 读取png像素点 RGBA 值   (png是4通道、jpg是3通道)  PNG:RGBA  JPG:RGB
                r, g, b, a = pixels[x, y]
                # starting_height 是像素开始更改的位置,也是我们设置拼图要放的地方(高度)
                # 将空白图片的某像素点,更改为当前拼图的像素点,以达到小拼图变长图的目的
                new_image.putpixel((x, starting_height + y), (r, g, b, a))
        if save_file:
            if save_file_path:
                new_image.save(save_file_path + '.png')
            else:
                # 保存最终图片  随机名称
                new_image.save(''.join(str(time.time()).split('.') + [".png"]))
        buffered = io.BytesIO()
        # 将数据写入buffered里
        new_image.save(buffered, format="PNG")
        return base64.b64encode(buffered.getvalue()).decode()


    # 将小拼图内透明不一的杂质全部改为透明
    def slider_puzzle_remove_tm(self,
                                p_puzzle_path: str = '',
                                save_file: bool = False,
                                save_file_path: str = ''):
        '''
        :param p_puzzle_path:  本地小拼图的路径
        :param save_file:  是否保存最终修改后的图片 默认False
        :param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
        :return: base64图片
        '''

        # 打开小拼图 图片
        image = Image.open(p_puzzle_path)
        width, height = image.size
        # 转为RGBA格式
        image = image.convert("RGBA")
        # 获取图片的像素数据
        pixels_1 = image.load()
        for x in range(height):
            for y in range(width):
                r, g, b, a = pixels_1[y,x]
                if a != 255:
                    r, g, b, a = 0,0,0,0
                # 将空白图片的某像素点,更改为当前拼图的像素点,以达到小拼图变长图的目的
                image.putpixel((y,x), (r, g, b, a))
        if save_file:
            if save_file_path:
                image.save(save_file_path + '.png')
            else:
                # 保存最终图片  随机名称
                image.save(''.join(str(time.time()).split('.') + [".png"]))
        buffered = io.BytesIO()
        # 将数据写入buffered里
        image.save(buffered, format="PNG")
        return {'base64': base64.b64encode(buffered.getvalue()).decode()}


    # 将正常大拼图转换为小拼图, 使用前先去掉多余的透明
    def slider_puzzle_qg(self,
                         p_puzzle_path: str = '',
                         save_file: bool = False,
                         save_file_path: str = ''):
        '''
        :param p_puzzle_path:  本地长拼图的路径
        :param save_file:  是否保存最终修改后的图片 默认False
        :param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
        :return: base64图片
        '''

        # 打开大拼图图片
        image = Image.open(p_puzzle_path)
        width, height = image.size
        pixels = image.load()
        # 采用红绿灯模式 存储和记录信息
        # _a:第一层-行数  _b:第二层-行数  _c:第三层-行数  k:记录拼图的像素数据
        _a = 0  # 红灯-最顶层 - 透明
        _b = 0  # 黄灯-中间层 - 数据核心 - 拼图的像素
        _c = 0  # 绿灯-最底层 - 透明
        k = []  # 将拼图的像素存储, 存储为一维数组
        buffered = io.BytesIO()
        for x in range(height):
            # 临时的行数据像素 - 左右
            data_pixel = []
            for y in range(width):
                # 读取png像素点 RGBA 值   (png是4通道、jpg是3通道)  PNG:RGBA  JPG:RGB
                r, g, b, a = pixels[y, x]
                data_pixel += [(r, g, b, a)]
            # 转换为NumPy数组
            NumPy_data_pixel = np.array(data_pixel)
            # 计算一整行像素值是否为透明, 是透明则跳过并记录在红绿灯内, 如果不是透明则将数据进行存储并记录在红绿灯内
            # True:透明(无数据)   False:不透明(有数据)
            if np.all(NumPy_data_pixel == 0):
                if _b == 0:
                    # 记录最顶层的行数 - 小拼图距离顶部的距离
                    _a += 1
                else:
                    # 当开始底层为0时,则表示第一次执行此命令,则要存储刚刚所保存的一维像素数组数据, 保存为图片
                    if _c == 0:
                        # 创建空白图片 - 宽:拼图的宽度   高:通过数据层获取    颜色:透明  格式:png
                        new_image = Image.new('RGBA', (width, _b), color=(0, 0, 0, 0))
                        # 采用一维的像素组数据写入图片
                        new_image.putdata(k)
                        # 将数据写入buffered里
                        new_image.save(buffered, format="PNG")
                        if save_file:
                            if save_file_path:
                                new_image.save(save_file_path + '.png')
                            else:
                                # 保存最终图片  随机名称
                                new_image.save(''.join(str(time.time()).split('.') + [".png"]))
                    # 记录最底层的行数 - 小拼图距离底部的距离
                    _c += 1
            else:
                # 记录拼图的有多少行-高度-上下距离-仅拼图的高度
                _b += 1
                # 拼图的像素数据 一维
                k += data_pixel
        # 最后返回字典格式数据
        return {
            '最顶层-顶层距离': _a,
            '中间层-拼图的高度': _b,
            '最底层-底层距离': _c,
            'base64': base64.b64encode(buffered.getvalue()).decode()
        }

    # 滑块识别距离, 放入完整滑块背景图 和 残缺滑块背景图
    def slider_identify_background(self,file_1, file_2,strict=0):
        '''
        :param file_1: 完整滑块背景图
        :param file_2: 残缺滑块背景图
        :param strict: 严格模式 针对极验, 当残缺滑块和完整滑块的像素有差别时,需要填写最多不能相差多少像素, 建议200以下,200即可
        :return: {w:滑道距离}
        '''
        # 打开图片
        image_1 = Image.open(file_1)
        image_2 = Image.open(file_2)
        # 获取图片的像素数据
        pixels_1 = image_1.load()
        pixels_2 = image_2.load()
        # 循环图片的宽度 左右距离
        for w in range(239):
            # 循环图片的长度/高度 上下距离
            for h in range(149):
                # 第一张缺口图 循环每一个像素
                color1 = pixels_1[w, h]
                # 第二张完整图 循环每一个像素
                color2 = pixels_2[w, h]
                if strict:
                    # 严格模式,检测变化较大的参数, 如果存在则表示缺口很明显
                    if (-strict > sum(np.array(color1)-np.array(color2))) or ((sum(np.array(color1)-np.array(color2))) > strict):
                        return {'w': w}
                else:
                    # 检测两张图的像素是否有变化,如果像素有变化,说明有缺口,则直接返回宽度即可,长度可以不要
                    if color1 != color2:
                        return {'w': w}
        return {'w': '未计算出!!!'}



    # 将滑块背景图切割为小滑道
    def background_cutting(self,
                           b_puzzle_path: str = '',
                           b_size_h: int = 0,
                           p_size_h: int = 0,
                           save_file: bool = False,
                           save_file_path: str = ''):
        '''
        :param b_puzzle_path:  本地滑块背景图的路径
        :param b_size_h:  小拼图在背景图中的所在高度,上下距离
        :param p_size_h:  小拼图的高度大小
        :param save_file:  是否保存最终修改后的图片 默认False
        :param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
        :return: base64图片
        '''
        # 打开图片
        image = Image.open(b_puzzle_path)
        width, height = image.size
        # 宽度,从左到右的距离
        left, right = 0, width
        # 高度,从上到下的距离
        top, bottom = b_size_h, b_size_h + p_size_h
        # 切割图片
        cropped_image = image.crop((left, top, right, bottom))
        if save_file:
            if save_file_path:
                cropped_image.save(save_file_path + '.png')
            else:
                # 保存最终图片  随机名称
                cropped_image.save(''.join(str(time.time()).split('.') + [".png"]))
        buffered = io.BytesIO()
        # 将数据写入buffered里
        cropped_image.save(buffered, format="PNG")
        return {'base64': base64.b64encode(buffered.getvalue()).decode()}


    # 滑块背景图还原 - 极验3.0
    def background_reduction(self,
                             b_puzzle_path: str = '',
                             save_file: bool = False,
                             save_file_path: str = ''):
        '''
        :param b_puzzle_path:  本地滑块背景图的路径 可处理3.0极验
        :param save_file:  是否保存最终修改后的图片 默认False
        :param save_file_path:  保存最终修改后的图片名称,不含后缀    默认:自动生成
        :return: base64图片
        '''
        # 打开PNG图片
        image = Image.open(b_puzzle_path)
        # 创建新的空白图片
        new_image = Image.new('RGBA', (260, 160))
        # 坐标
        k = 0
        # 定值, 在极验3.0版本中, 通过画布断点获取数据
        ut = [39,38,48,49,41,40,46,47,35,34,50,51,33,32,28,29,27,26,36,37,31,30,44,45,43,42,12,13,23,22,14,15,21,20,8,9,25,24,6,7,3,2,0,1,11,10,4,5,19,18,16,17]
        # ut有多少参数, 就有多少个小碎片拼图
        for _ in range(len(ut)):
            # 通过计算得出 小碎片的起始坐标
            c = ut[_] % 26 * 12 + 1
            # 计算是否当前小碎片在第一层还是第二层, 三元表达式
            u = (lambda: 80 if 25 < ut[_] else 0)()
            # 将裁切下来小碎片的数据存储
            image2 = image.crop((c, u, c + 10, u + 80))
            # 当存储量达到26, 则重置小碎片的放置坐标, 每层只能放26小碎片
            if _ == 26:
                k = 0
            if _ > 25:
                # 第二层
                new_image.paste(image2, (k, 80))
                k += 10
            else:
                # 第一层
                new_image.paste(image2, (k, 0))
                k += 10
        if save_file:
            if save_file_path:
                new_image.save(save_file_path + '.png')
            else:
                # 保存最终图片  随机名称
                new_image.save(''.join(str(time.time()).split('.') + [".png"]))
        buffered = io.BytesIO()
        # 将数据写入buffered里
        new_image.save(buffered, format="PNG")
        return {'base64': base64.b64encode(buffered.getvalue()).decode()}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1538409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPF 立体Border

WPF 立体Border &#xff0c;用来划分各个功能区块 在资源文件中&#xff0c;添加如下样式代码&#xff1a; <Style x:Key"BaseBorder" TargetType"Border"><Setter Property"Background" Value"White" /><Setter Prop…

RuoYi-Vue-Plus(基础知识点jackson、mybatisplus、redis)

一、JacksonConfig 全局序列化反序列化配置 1.1yml中配置 #时区 spring.jackson.time-zoneGMT8 #日期格式 spring.jackson.date-formatyyyy-MM-dd HH:mm:ss #默认转json的属性&#xff0c;这里设置为非空才转json spring.jackson.default-property-inclusionnon_null #设置属性…

【数据结构】——栈与队列(附加oj题详解)深度理解

栈 1.栈的定义 栈&#xff1a;栈是仅限与在表尾进行插入或者删除的线性表 我们把允许一端插入和删除的一端叫做栈顶&#xff0c;另一端叫栈底&#xff0c;不含任何元素的栈叫做空栈&#xff0c;栈又叫做后进先出的线性表&#xff0c;简称LIFO结构 2.栈的理解 对于定义里面…

lvs+keepalived+nginx实现高可用

主机&#xff1a;192.168.199.132 备机&#xff1a;192.168.199.133 真实服务器1&#xff1a;192.168.199.134 真实服务器2&#xff1a;192.168.199.135 问题&#xff1a; 防火墙没关 132配置ipvsadm进行dr模式 132配置keepalived.conf 133配置ipvsadm进行dr模式 133配置ke…

数据结构(五)——二叉树的遍历和线索二叉树

5.3. 二叉树的遍历和线索二叉树 5.3.1_1 二叉树的先中后序遍历 遍历&#xff1a;按照某种次序把所有结点都访问一遍 二叉树的递归特性&#xff1a; ①要么是个空二叉树 ②要么就是由“根节点左子树右子树”组成的二叉树 先序遍历&#xff1a;根左右&#xf…

深度学习中的随机种子random_seed

解释 由于模型中的参数初始化例如权重参数如下图&#xff0c;就是随机初始化的&#xff0c;为了能够更好的得到论文中提到效果&#xff0c;可以设置随机种子&#xff0c;从而减少算法结果的随机性&#xff0c;使其接近于原始结果。 设置了随机种子&#xff0c;产生的随机数都…

硬核分享|AI语音识别转文字与自动生成字幕

硬核分享|AI语音识别转文字与自动生成字幕_哔哩哔哩_bilibili 在现代快节奏的生活中&#xff0c;语音转文字工具成为了我们工作和学习中的得力助手。它能够将我们说出的话语迅速转化为文字或者将语音视频自动生成字幕&#xff0c;提供便捷和高效。 语音转文字转字幕工具是一种…

spring boot商城、商城源码 欢迎交流

一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、防范xss攻击、拥有分布式锁&#xff0c;为生产环境多实例完全准备&#xff0c;数据库为b2b2c设计&#xff0c;拥有完整sku和下单流程的商城 联系: V-Tavendor

计算机网络:分层体系结构

计算机网络&#xff1a;分层体系结构 基本分层概述各层次的任务物理层数据链路层网络层运输层应用层 数据传递过程分层体系常见概念实体协议服务 基本分层概述 为了使不同体系结构的计算机网络都能互联&#xff0c;国际标准化组织于 1977 年成立了专门机构研究该问题。不久他们…

不启动BMIDE,Teamcenter如何查看property的real property name

问题描述&#xff1a; Teamcenter客户端&#xff0c;查看Item 属性&#xff0c;属性名称默认显示的是Display Name。 在各类开发过程中&#xff0c;对属性的操作&#xff0c;需要使用real property name才能进行。开发可能不在server端&#xff0c;没有安装BMIDE&#xff0c;如…

4核16G服务器租用优惠价格,26.52元1个月,半年149元

阿里云4核16G服务器优惠价格26.52元1个月、79.56元3个月、149.00元半年&#xff0c;配置为阿里云服务器ECS经济型e实例ecs.e-c1m4.xlarge&#xff0c;4核16G、按固定带宽 10Mbs、100GB ESSD Entry系统盘&#xff0c;活动链接 aliyunfuwuqi.com/go/aliyun 活动链接打开如下图&a…

Linux设备驱动开发 - 三色LED呼吸灯分析

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 展锐UIS7885呼吸灯介绍呼吸灯调试方法亮蓝灯亮红灯亮绿灯展锐UIS7885呼吸灯DTS配置ump9620 PMIC驱动ump9620中的LED呼吸灯驱动LED的tr…

python框架的一加剧场管理系统的设计与实现flask-django-nodejs-php

本文讲述了一加剧场管理系统。结合电子管理系统的特点&#xff0c;分析了一加剧场管理系统的背景&#xff0c;给出了一加剧场管理系统实现的设计方案。 本论文主要完成不同用户的权限划分&#xff0c;不同用户具有不同权限的操作功能&#xff0c;在用户模块&#xff0c;主要有用…

数据挖掘与分析学习笔记

一、Numpy NumPy&#xff08;Numerical Python&#xff09;是一种开源的Python库&#xff0c;专注于数值计算和处理多维数组。它是Python数据科学和机器学习生态系统的基础工具包之一&#xff0c;因为它高效地实现了向量化计算&#xff0c;并提供了对大型多维数组和矩阵的支持…

开源数据集 nuScenes 之 3D Occupancy Prediction

数据总体结构 Nuscenes 数据结构 可以看一下我的blog如何下载完整版 mmdetection3d ├── mmdet3d ├── tools ├── configs ├── data │ ├── nuscenes │ │ ├── maps │ │ ├── samples │ │ ├── sweeps │ │ ├── lidarseg (o…

PHP 读取嵌入式数据 SQLite3

SQLite3 属于轻量级开源的嵌入式关系型数据库&#xff0c;但它支持 ACID(Atomicity,Consistency,Isolation,Durability) 事务。 SQLite Download Page: https://www.sqlite.org/download.html 第一步&#xff1a;在 php.ini 中开启 extensionsqlite3 第二步&#xff1a;连接数…

K8s+Nacos实现应用的优雅上下线【生产实践】

文章目录 前言一、环境描述二、模拟请求报错三、配置优雅上下线1.修改nacos配置2.修改depolyment配置3.重新apply deployment后测试4.整体(下单)测试流程验证是否生效 四、期间遇到的问题 前言 我们在使用k8s部署应用的时候&#xff0c;虽然k8s是使用滚动升级的&#xff0c;先…

畅谈AIGC,ISIG-AIGC技术与应用发展峰会成功举办

3月16日&#xff0c;第四届ISIG中国产业智能大会在上海中庚聚龙酒店如期开幕&#xff0c;此次大会由苏州市金融科技协会指导、企智未来科技&#xff08;RPA中国、LowCode低码时代、AIGC开放社区&#xff09;主办。大会聚集了来自不同领域的专家学者、行业领军人物及技术研发者&…

MySQL 更新执行的过程

优质博文&#xff1a;IT-BLOG-CN Select语句的执行过程会经过连接器、分析器、优化器、执行器、存储引擎&#xff0c;同样的 Update语句也会同样走一遍 Select语句的执行过程。 但是和 Select最大不同的是&#xff0c;Update语句会涉及到两个日志的操作redo log&#xff08;重做…

python的街道办管理系统flask-django-php-nodejs

随着世界经济信息化、全球化的到来和互联网的飞速发展&#xff0c;推动了各行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、动态的、交互友好的、高效的街道办管理系统。当前的信息管理存在工作效率低…