本帖最后由 waynewange 于 2023-11-18 11:00 编辑
来啦,来啦,反正闲着也是闲着,那就折腾呗! 不是发了生成验证码图片么,有版友问滑块怎么实现呢? 于是我找GPT问了一下,加上自己也有点思路,刚刚好一结合。嗯,效果不错 源码需怕python环境,以及需安装了PIL这个库 楼主的表达能力真心不怎么样,只能大概介绍一下思路了, 基本实现方式是打开一张图片,随机取图片的一个点,以这个点为中心向上下左右各50个像素裁剪出一个100*100的正方形小图片,作为滑块的活动图片, (其实在这个阶段想的很多,感觉还有蛮大的可操作空间,例如作为滑块的大图那个白色的地方还可以加点干扰点,或者白色背景改为随机颜色)不能给自己留坑,我还没学会javascript逆向呢,所以不写了。
图片备好其他就简单了,借助与tkinter模块的bind函数监控拖动滑块,让小滑块的x与大滑块裁剪时随机的那个终点重回就好了 (其实这里也想随机的,不一定只能左右移啊,也可以上下移动的,或者斜线移动,就跟抽签一样抽中x就x移动,抽中y就上下移动,不写了,不想动了) 基本就这些了吧,以下是源码 import random import tkinter import os from PIL import Image, ImageTk from tkinter import messagebox def slider(image): """ 从图片上截下一个小滑块, 并同时保存小滑块与扣掉小滑块的图片 """ global img_x, img_y # 先从图片上随机定位出一个点,作为滑块的中心点 img_x = random.randint(image_width//2-60, image_width-60) # 先从图片右半部分随机获取出一个x点,不要定位到图片外界去 img_y = random.randint(60, image_height-60) # 剪裁像素为100*100的小图所以边框位置留60个像素,避免越界切到图外去了 # 以定位出来的点剪裁出一个大小为100*100的小滑块图片 x1, y1, x2, y2 = img_x-50, img_y-50, img_x+50, img_y+50 # 左上角和右下角坐标 # 裁剪小图 small_image = image.crop((x1, y1, x2, y2)) # 根据坐标剪裁小图片 # 保存小图 small_image.save(small_image_path) small_image.close() # 裁剪大图 cropped_image = image.copy() try: cropped_image.paste((255, 255, 255), (x1, y1, x2, y2)) # 将裁剪区域涂白,有些环境这里报错,加个异常处理 except: cropped_image.paste(300, (x1, y1, x2, y2)) # 保存大图 cropped_image.save(big_image_path) cropped_image.close() def on_click(event): global is_mouse_dragged """ 鼠标按下触发事件 """ # 处理鼠标左键按下并移动的操作 is_mouse_dragged = True # 获取鼠标单击的坐标 x = event.x # 避免移动图像超出大图边界 if x < 50: x = 60 elif x > image_width-50: x = image_width-60 # 更新图像位置 canvas.coords(image_item, x-50, img_y-50) # 图片像素为100*100的减50将鼠标点居于图片中心 def func(event): global is_mouse_dragged """ 鼠标松开触发事件, 鼠标松开检查是否对齐滑块 """ # 只有当鼠标按下并拖动过滑块才能完全触发判定 if not is_mouse_dragged: return else: is_mouse_dragged = False if (img_x-5) <= event.x <= (img_x+5): # 大图x方向与小图滑块对齐容错左右各5个像素 messagebox.showinfo("信息", "操作成功!") else: messagebox.showerror("错误", f"不是这个位置\n") def update_coordinates(event): x = event.x y = event.y label.config(text=f"X 坐标:{x}, Y 坐标:{y}") if __name__ == '__main__': img_x, img_y = 0, 0 # 记录剪裁滑块中心点在原图的位置 is_mouse_dragged = False # 检测按下鼠标移动后才会触发松开按键的事件 image_path = r"C:\Users\Administrator\Desktop\111\image.png" # 指定一个图片路径 path_dir = os.path.split(image_path)[0] big_image_path = os.path.join(path_dir, 'path_to_cropped_image.png') # 大图像路径 small_image_path = os.path.join(path_dir, 'path_to_small_image.png') # 小图像路径 root = tkinter.Tk(className='滑块验证模拟') image = Image.open(image_path) photo = ImageTk.PhotoImage(image) # 将image转为tkinter可以显示的对象图片 width = root.winfo_screenwidth() # 获取屏幕宽度 height = root.winfo_screenheight() # 获取屏幕高度 image_width = image.width # 获取图片宽 image_height = image.height # 获取图片高 win_width = (width-image_width)//2 win_height = (height-image_height)//2 root.geometry(f'{image_width}x{image_height}+{win_width}+{win_height}') # 以图片大小创建窗口大小,并让窗口居中屏幕 slider(image) # 切出大小图 label = tkinter.Label(root, text="鼠标坐标") label.pack() # 创建Canvas控件并显示大图 canvas = tkinter.Canvas(root, width=image_width, height=image_height) canvas.pack() big_image = tkinter.PhotoImage(file=big_image_path) canvas.create_image(0, 0, anchor="nw", image=big_image) # 显示小图 small_image = tkinter.PhotoImage(file=small_image_path) image_item = canvas.create_image(10, img_y-50, anchor="nw", image=small_image) # 500, 100小图坐标的起始位置 # 绑定鼠标单击事件 root.bind("<Motion>", update_coordinates) canvas.bind("<B1-Motion>", on_click) # 鼠标按下拖动滑块 canvas.bind("<ButtonRelease-1>", func) # 鼠标松开检测是否重合 root.mainloop()
接着再配置图片,其实只要把代码的79行中的C:\Users\Administrator\Desktop\1111\image.png改为任意png后缀的图片路径都能玩的,其他图片理论上也支持的,自行测试吧!
注:若转载请注明大神论坛来源(本贴地址)与作者信息。
|