Image Tools图片坐标提取软件/图片截图工具/图片坐标点和像素点颜色提取软件/图片坐标获取工具/Python图片坐标获取源码/图片像素坐标获取软件/查看图片点XY坐标(完全开源)

该软件使用python写的,可以提取像素点的坐标还有也能获取像素点的16进制数据RGB565和RGB888(RGB888仅最新的源码才支持),可以单点坐标也可以按键坐标,甚至可以使用简单的左右键配合使用,自动复制到粘贴板,如果图片太大或者太小,也支持图片缩小放大,但是软件会对像素进行处理不建议这么干,截图工具可以截取对应区域的图片,并输出,类似于微信的截图,同时也能保存坐标点

功能:    

1、获取像素点坐标

2、获取矩形区域坐标

3、获取贴图坐标

4、获取像素点十六进制颜色(RGB565/RGB888)

5、自动获取信息并复制到粘贴板

6、截图

7、保存坐标点到Excel表文件

8、修正坐标信息显示

9、图片放大缩小

10、批量图片格式转换

该软件支持现有常用格式的bmp、jpg、gif和png等格式,也可以自定义xy复制到粘贴板的比例。

程序已经打包成exe文件可直接双击运行,但是做了使用两年后强制更新(为了点积分),到时候再回来这个博客重新下载最新版的就好了,如果不想要可以在最下面的源码里面自己打包一份

exe文件在以下链接(推荐其他的下载方式支持开源,或者点赞评论不做白嫖怪)(205.03.31更新):

百度网盘链接:https://pan.baidu.com/s/1aoE8RcjAgMZQ7BJ9zaKe1Q?pwd=a8b1 
提取码:a8b1

如果需要自己修改,使用pyinstaller -F -w  指令来完成打包

打包步骤是打开cmd窗口,输入:pip install pyinstaller(安装pyinstaller,已经安装可跳过)

其他第三方库安装命令:

安装opencv : pip install opencv-python

安装pillow:pip install pillow

安装ny库:pip install numpy

安装pyperclip库:pip install pyperclip

安装openpyxl库:pip install openpyxl

然后输入pyinstaller -F -w 【文件路径】

例如:pyinstaller -F -w C:\\Users\MSN\Desktop\11\PythonApplication1.py

如果openCV无法打包则可以尝试使用此指令:pyinstaller -F -w C:\\Users\MSN\Desktop\11\ImageToolsv2.0.py --hidden-import opencv-python

也可以参考此链接Python PyInstaller安装和使用教程(详解版) (biancheng.net)

运行平台已经测试过win7,win8,win10,Win11都能运行(V1.7版本以下,V1.9以上可能需要单独下载各自系统的exe文件)

以下是最新完整工程源码和exe执行文件链接(最新更新2025.03.31):

像素点坐标提取源码/Python提取图片坐标/Python图片坐标获取源码-Python文档类资源

最新打包好的最新的exe,更好的GUI布局,支持窗口自由放大缩小和格式转换(最新更新2025.03.31):

Python图片像素点坐标提取工具/Python提取图片坐标软件/迪文图片坐标获取工具

在后面的版本中有些第三方库存在系统兼容性问题,因此对windows各版本单独生成了独立的exe可执行文件,在以下的百度网盘链接中,源码维持不变

使用方法:图片坐标点和像素颜色获取/图片截图小工具_哔哩哔哩_bilibili

最新源码还是粘贴在最下面,加了注释

如有相关问题或者好建议可联系:QQ:1257784610

以下是最新更新展示

8065492a811b47c78f8cc44cfadbb027.png

 不再限制图片格式,将所有文件都能看到

5ec2be1024e54745bf86e77de9ddfb57.png

新增的图片截图小功能展示:

然后就能在输出路径找到截图

2024.10.21新增坐标保存功能展示:

首次会跳出导出文件窗口

保存后按钮会更改为保存到下一行,此时已经保存了第一个点,后续的点会在下一行继续,点一下保存当前已经获取的像素坐标

自动追加XY坐标点

如果要重新记录,删除文件重新开始应用程序或者重新打开应用程序在导出文件中修改其他命名

2025.03.31新增图片格式转换:

自动获取/快捷键功能:

鼠标左键单击:        像素坐标
鼠标左键按下移动:    矩形坐标
鼠标滚轮单击:        像素颜色
鼠标右键按下并移动:    贴图坐标

ctrl+鼠标滚轮:图片放大缩小
键盘按键(S):保存坐标
键盘按键(P):图片截图
键盘按键(O):打开图片
键盘按键(R):复位图片
键盘按键(向上方向键):图片放大
键盘按键(向下方向键):图片缩小
键盘按键(pgup):图片放大
键盘按键(pgdn):图片缩小

矩形坐标:(左上角X坐标,左上角Y坐标,右下角X坐标,右下Y坐标)

贴图坐标就是一个矩形坐标+放的坐标:(左上角X坐标,左上角Y坐标,右下角X坐标,右下Y坐标,左上角X坐标,左上角Y坐标)(此功能适合嵌入式贴图编程)

像素坐标就是一个点坐标:(X坐标,Y坐标)

Ctrl+鼠标上下滚轮可以缩小放大图片

像素颜色是16进制的RGB565和RGB888,默认是RGB565,勾上后输出RGB888

自动复制是指操作后坐标数据自动拷贝到粘贴板上

转换系数是指:比如我需要把800*600的图坐标放大为1024*768,就往里面输入1024/768 = 1.28,输入1.28并且点击设置xy系数就能获取比例放大的坐标信息,注意这个不会修改图片的任何信息,要保持原来的就输入1,算法是:显示的X坐标 = 获取的X坐标*X比例系数     

        例如:800 * 1.28 = 1024

把自动获取取消后,单击就是对应的坐标

软件也支持图片快捷键ctrl+鼠标滚轮进行缩小放大,但是不建议缩太小和放太大,除非你的电脑配置顶天,同时此功能会影响最大像素值的大小,放大缩小越多,误差会越大,请慎重使用 

8c841ca650c54bba9a6f73a6a78879e7.png

下面的都是源码(旧源码),但是由于时间仓促并没有对代码进行整理,不然的话可以更简洁,由于工作使用的都是C语言,因此代码逻辑很像C语言,如果哪天我有空我会对代码进行整理,编译软件我用的是微软的VS2022,也可以使用Python 3.10版本的IDLE进行编程以下是代码所需的库,有特殊需求的可以自己修改源码 

最新的源码可以自己去上面的链接中获取,如果不用RGB888的话,旧版的也够用了 

相比于第一版,后期更新支持如下

1、支持RGB888和RGB565

2、支持图片自由放大缩小(快捷键ctrl+鼠标滚轮)

3、新增图片复位

4、最大化不会gui布局错误

5、修复部分bug

6、图片放大缩小算法由近邻法修改为面积插值法

2024.04.11更新,版本号到V2.0:

1、新增了鼠标位置在画布中实时更新

2、不再限制图片格式,不用再单独选bmp或者jpg

3、新增代码注释,优化代码变量命名(起码能看懂一点了)

2024.5.20更新,版本号到V2.2:

1、新增了像素和坐标实时显示

2、新增放大缩小百分比显示

3、新增截图小功能

4、优化变量不再使用小数点表示放大缩小倍数

2024.8.15更新,版本号到V2.3:

1、新增十字光标显示

2、修复部分bug

2024.10.21更新,版本到V2.5:

1、新增像素坐标保存到Excel文件中

2、归类部分重复代码

3、优化十字光标显示

2024.10.28更新,版本到V2.6:

1、修复十字光标滚动后不能精准定位

2024.11.21更新,版本到V2.7:

1、修复获取像素颜色错误

2024.12.25更新,版本到V2.8:

1、新增快捷键功能

2、指定保存时的文件格式

2025.03.31更新,版本到V3.0:

1、新增图片格式转换功能

代码全部粘贴在最后

以下是代码所需库  

from asyncio.windows_events import NULL
import tkinter as tk
import pyperclip
from PIL import Image
from PIL import ImageTk
from tkinter import filedialog
import sys

以下是程序所需宏定义,像素数单双都行

sys.setrecursionlimit(100000) #设置递归深度
#像素数必须为双数
Start_x = 1
Start_y = 1
End_x = 2
End_y = 2
YRadioVar = 1.0000
XRadioVar = 1.0000
Image



        以下是Python新增创建组件和窗口的代码

ws = tk.Tk()
ws.title('Guides QQ:1257784610')
ws.geometry('1100x700+888+444')
pw1=tk.PanedWindow(ws,orient=tk.HORIZONTAL,width = 100,height = 100,sashrelief='groove') # 创建横向分割面板
pw1.pack(fill=tk.BOTH,expand=True) # 尺寸扩展到整个窗体
frame = tk.Frame(pw1 ,width = 900,height = 700)
ws.update_idletasks()
get_fp = filedialog.askopenfilename(filetypes = [("BMP",".bmp"),("PNG",".png"), ("GIF",".gif"),("JPG",".jpg")])


ws.title('Guides QQ:1257784610    '+str(get_fp))
image = Image.open(get_fp)
#获取图片像素点大小
high = image.height   #高度
width = image.width  #宽度
#print(high,width)
if (high%2) != 0:
    high = high-1
if (width%2) != 0:
    width = width-1
canvas=tk.Canvas(
    frame,
    
    bg='#4A7A8C',
    width=100,
    height=100,
    scrollregion=(2,2,width+3,high+3)     #  2改为0会导致光标和画布有点偏移,取消滚动功能就正常
    )
canvas.imagecolor = image.convert('RGB')
canvas.src_strlist = canvas.imagecolor.load()
R,G,B = canvas.src_strlist[1, 1]
px = str(hex((R>>3)<<11 | (G>>2)<<5 | B>>3))
#垂直
vertibar=tk.Scrollbar(
    frame,
    orient=tk.VERTICAL
    )
vertibar.pack(side=tk.RIGHT,fill=tk.Y)
vertibar.config(command=canvas.yview)
#水平
horibar=tk.Scrollbar(    
    frame,
    orient=tk.HORIZONTAL
    )
horibar.pack(side=tk.BOTTOM,fill=tk.X)
horibar.config(command=canvas.xview)
canvas.config(
    xscrollcommand=horibar.set, 
    yscrollcommand=vertibar.set
    )
canvas.img_avatar  = ImageTk.PhotoImage(image)
#imgLabel = tk.Label(frame ,image = photo)
#imgLabel.pack()
tk.canvasimage = canvas.create_image(float(width/2)+2,float(high/2)+2 , image=canvas.img_avatar ) #此处加2是为了全部显示
tk.rectangle1 = canvas.create_rectangle(0, 0 , 1 , 1 , outline = "red")

canvas.bind("<B1-Motion>" , B1_Motion)#鼠标事件
canvas.bind("<B3-Motion>" , B3_Motion)#鼠标事件
canvas.bind("<Button-1>" , Mouse_dowm)#鼠标事件
canvas.bind("<Button-3>" , Mouse_RIGHT_dowm)#鼠标事件
canvas.bind("<Button-2>" , Mouse_Middle_dowm)#鼠标事件
#ws.bind("<Configure>", adjust_scrollregion)
canvas.pack(expand=True,side=tk.LEFT,fill=tk.BOTH)
####################################################
v = tk.IntVar()
v.set(5)
v1 = tk.IntVar()
v1.set(1)
Coordinate = tk.StringVar()
Xradio1 = tk.StringVar()
Yradio1 = tk.StringVar()
pw2=tk.PanedWindow(pw1,orient=tk.VERTICAL,width = 100,height = 100,sashrelief='groove')
#pw2.pack(fill=tk.BOTH,expand=True) # 尺寸扩展到整个窗体
frame1 = tk.Frame(pw2)
frame2 = tk.Frame(pw2)
textLabel = tk.Label(frame1  ,text = '出现BUG请重启')
textLabel.grid(column = 0 , row = 0)
Coordinateout = tk.Entry(frame1 , width = 30 ,  text = Coordinate  , state = "readonly" , exportselection = 1)
Coordinateout.grid(column = 0 , row = 1)



LANGS= [("按键坐标" , 1),
        ("切图坐标" , 2),
        ("单点坐标" , 3),
        ("像素颜色" , 4),
        ("自动获取" , 5)]
for lang ,num in LANGS:
    b= tk.Radiobutton(frame2 , text = lang , variable = v , value = num )
    b.pack(fill =tk.X)

button6 = tk.Button(frame2 , text = "打开图片"  , command = OpenPicture)
button6.pack()
button7 = tk.Checkbutton(frame2 , text = "自动复制" , variable= v1)
button7.pack()

tk.Label(frame2 , text = '请输入X转换系数,默认为1').pack()

X_Radio = tk.Entry(frame2 , width = 20 ,  textvariable = 1, text = Xradio1   , exportselection = 1)
X_Radio.pack()
Xradio1.set(1)
tk.Label(frame2 , text = '请输入Y转换系数,默认为1').pack()

Y_Radio = tk.Entry(frame2 , width = 20 ,  textvariable = 1,text = Yradio1   , exportselection = 1)
Y_Radio.pack()
Yradio1.set(1)
button8 = tk.Button(frame2 , text = "设置XY系数"  , command = XYRadio_Set)
button8.pack()

#######################################################


pw1.add(frame) # pw1加入fr1组件
pw1.add(pw2) # pw1加入pw2组件
 
pw2.add(frame1) # pw2加入fr2组件
pw2.add(frame2) # pw2加入fr3组件

ws.mainloop()

以下是鼠标左键按下滑动事件调用的回调函数代码

def B1_Motion(event):
    global End_x
    global End_y
    radioup , raduodown = vertibar.get() 
    radioxleft , radioxright = horibar.get()
    #End_x,End_y = ((canvas.canvasx(event.x)+width * radioxleft)-2 ), ((canvas.canvasx(event.y) + high * radioup)-2) #-2才是对上像素
    End_x,End_y = ((event.x+width * radioxleft)-2 ), ((event.y + high * radioup)-2) #-2才是对上像素
    #canvas.delete(tk.ALL)


    if End_x<0 :
        End_x = 0;
    if End_y <0:
        End_y = 0;

    if End_x > width :
        End_x = width;
    if End_y > high:
        End_y = high;
        
    canvas.delete(tk.rectangle1)  
    tk.rectangle1 = canvas.create_rectangle(Start_x+2, Start_y+2 , End_x +2, End_y +2, outline = "red")#矫正显示矩形刚好对上光标
    
    if v.get() == 1 or v.get() == 5:
        result = str(int(Start_x*XRadioVar))+','+str(int(Start_y*YRadioVar))+','+str(int(End_x*XRadioVar))+','+str(int(End_y*YRadioVar))
        Coordinate.set(str(result))
        if v1.get() == 1:
            pyperclip.copy(result)
    elif v.get() == 2:
        result = str(int(Start_x*XRadioVar))+','+str(int(Start_y*YRadioVar))+','+str(int(End_x*XRadioVar))+','+str(int(End_y*YRadioVar))+','+str(int(Start_x*XRadioVar))+','+str(int(Start_y*YRadioVar))
        Coordinate.set(str(result))
        if v1.get() == 1:
            pyperclip.copy(result)
    canvas.update()

以下是鼠标右键按下滑动事件调用的回调函数代码

def B3_Motion(event):
    global End_x
    global End_y
    radioup , raduodown = vertibar.get() 
    radioxleft , radioxright = horibar.get()
    #End_x,End_y = ((canvas.canvasx(event.x)+width * radioxleft)-2 ), ((canvas.canvasx(event.y) + high * radioup)-2) #-2才是对上像素
    End_x,End_y = ((event.x+width * radioxleft)-2 ), ((event.y + high * radioup)-2) #-2才是对上像素
    if End_x<0 :
        End_x = 0;
    if End_y <0:
        End_y = 0;

    if End_x > width :
        End_x = width;
    if End_y > high:
        End_y = high;
    canvas.delete(tk.rectangle1)  
    tk.rectangle1 = canvas.create_rectangle(Start_x+2, Start_y+2 , End_x +2, End_y +2, outline = "red")#矫正显示矩形刚好对上光标
    result = str(int(Start_x*XRadioVar))+','+str(int(Start_y*YRadioVar))+','+str(int(End_x*XRadioVar))+','+str(int(End_y*YRadioVar))+','+str(int(Start_x*XRadioVar))+','+str(int(Start_y*YRadioVar))
    Coordinate.set(str(result))
    if v1.get() == 1:
        pyperclip.copy(result)
    '''canvas.src_strlist = canvas.imagecolor.load()
    R,G,B = canvas.src_strlist[End_x, End_y]
    px = str(hex((R>>3)<<11 | (G>>2)<<5 | B>>3))
    Coordinate.set(px)
    print(px)'''
    canvas.update()

以下是鼠标左键按下事件调用的回调函数代码

def Mouse_dowm(event):
    global Start_x
    global Start_y
    radioup , raduodown = vertibar.get() 
    radioxleft , radioxright = horibar.get()
    Start_x,Start_y = ((event.x+width * radioxleft)-2 ), ((event.y + high * radioup)-2)
    #canvas.create_oval(x1 , y1, x2, y2, fill = "red")
    if Start_x<0 :
        Start_x = 0;
    if Start_y <0:
        Start_y = 0;

    if Start_x > width :
        Start_x = width;
    if Start_y > high:
        Start_y = high;

    result = str(int(Start_x*XRadioVar))+','+str(int(Start_y*YRadioVar))
    if v.get() == 3 or v.get() == 5:
        Coordinate.set(str(result))
        if v1.get() == 1:
            pyperclip.copy(result)
    elif v.get() == 4 :
        
        if Start_x<width and Start_y<high:
            canvas.src_strlist = canvas.imagecolor.load()
            R,G,B = canvas.src_strlist[Start_x, Start_y]
            px = str(hex((R>>3)<<11 | (G>>2)<<5 | B>>3))
            Coordinate.set(px)
            if v1.get() == 1:
                pyperclip.copy(px)
    canvas.update()

以下是鼠标滚轮键按下事件调用的回调函数代码

def Mouse_Middle_dowm(event):
    global Start_x
    global Start_y
    radioup , raduodown = vertibar.get() 
    radioxleft , radioxright = horibar.get()
    Start_x,Start_y = ((event.x+width * radioxleft)-2 ), ((event.y + high * radioup)-2)
    #canvas.create_oval(x1 , y1, x2, y2, fill = "red")
    if Start_x<0 :
        Start_x = 0;
    if Start_y <0:
        Start_y = 0;

    if Start_x > width :
        Start_x = width;
    if Start_y > high:
        Start_y = high;

    if Start_x<width and Start_y<high:
        canvas.src_strlist = canvas.imagecolor.load()
        R,G,B = canvas.src_strlist[Start_x, Start_y]
        px = str(hex((R>>3)<<11 | (G>>2)<<5 | B>>3))
        Coordinate.set(px)
        if v1.get() == 1:
            pyperclip.copy(px)
    canvas.update()

以下是鼠标右键按下事件调用的回调函数代码

def Mouse_RIGHT_dowm(event):
    global Start_x
    global Start_y
    radioup , raduodown = vertibar.get() 
    radioxleft , radioxright = horibar.get()
    Start_x,Start_y = ((event.x+width * radioxleft)-2 ), ((event.y + high * radioup)-2)
    #canvas.create_oval(x1 , y1, x2, y2, fill = "red")
    if Start_x<0 :
        Start_x = 0;
    if Start_y <0:
        Start_y = 0;

    if Start_x> width :
        Start_x = width;
    if Start_y > high:
        Start_y = high;
    result = str(int(Start_x*XRadioVar))+','+str(int(Start_y*YRadioVar))
    Coordinate.set(str(result))
    canvas.update()

以下是打开图片路径并读取调用的回调函数代码

def OpenPicture():
    global high
    global width
    global R
    global G
    global B
    global px
    #canvas.delete(tk.canvasimage)
    get_fp = filedialog.askopenfilename(filetypes = [("BMP",".bmp"),("PNG",".png"), ("GIF",".gif"),("JPG",".jpg")])
    image = Image.open(get_fp)
    ws.title('Guides QQ:1257784610    '+str(get_fp))
    #获取图片像素点大小
    high = image.height   #高度
    width = image.width  #宽度
    #canvas.delete("all")
    
    #print(high,width)
    if (high%2) != 0:
        high = high-1
    if (width%2) != 0:
        width = width-1
    
    canvas.img_avatar = ImageTk.PhotoImage(image)
    canvas.imagecolor = image.convert('RGB')
    canvas.config(
        width=100,
        height=100,
       scrollregion=(2,2,width+3,high+3) )    #  2改为0会导致光标和画布有点偏移,取消滚动功能就正常 ,此为画布元祖坐标,这里重定画布大小)
    tk.canvasimage = canvas.create_image(float(width/2)+2,float(high/2)+2 , image=canvas.img_avatar ) #此处加2是为了全部显示
    #canvas.after(image=photo)
    #canvas.configure(image = photo)
    
    canvas.itemconfig(tk.canvasimage, image=canvas.img_avatar)
    canvas.update()
    return

以下是XY坐标按键系数调用回调函数代码

def XYRadio_Set():
    global YRadioVar
    global XRadioVar
    XRadioVar = float(X_Radio.get())
    YRadioVar = float(Y_Radio.get())

最新源码在此全部粘贴(2025.03.31

from ast import Lambda
from asyncio.windows_events import NULL
from cgitb import text
from csv import excel
import time
from threading import Thread
from tkinter import *
import datetime
import tkinter as tk
from unittest import result
import cv2 as cv
import os
import numpy as np
import pyperclip
from PIL import Image
from PIL import ImageTk
from tkinter import filedialog
from tkinter import ttk
import openpyxl as opxl
import sys
sys.setrecursionlimit(100000) #设置递归深度
#像素数必须为双数
'''Start_x = 1
Start_y = 1
End_x = 2
End_y = 2
YRadioVar = 1.0000#Y坐标比例
XRadioVar = 1.0000#X坐标比例
zoomRadioVar = 1.0000#缩放比例
YSetRadioVar = 1.0000#Y坐标比例
XSetRadioVar = 1.0000#X坐标比例
Win_height = 700
Win_width = 1100

Win_heightbuffer = 700
Win_widthbuffer = 1100'''
#whiletimes = 0

class Callback():
    def __init__(self,root):
        #初始化所有数据
        self.矩形坐标 = 1
        self.贴图坐标 = 2
        self.单点坐标 = 3
        self.像素颜色 = 4
        self.自动获取 = 5
        self.截图输出 = 6
        self.root = root
        self.image = NULL#图片缓冲
        self.Start_x = 1#记录鼠标开始x坐标
        self.Start_y = 1#记录鼠标开始Y坐标
        self.End_x = 2#记录鼠标结束x坐标
        self.End_y = 2#记录鼠标结束y坐标
        self.high = 0#记录图片高有多少个像素
        self.width = 0#记录图片宽有多少个像素
        self.px = NULL#记录图片像素点颜色
        self.get_fp = NULL#文件路径
        self.R = 0#红色的数值
        self.G = 0#绿色的数值
        self.B = 0#蓝色的数值
        self.Current_x = 0#用于第二entry显示,鼠标移动的坐标
        self.Current_y = 0#用于第二entry显示,鼠标移动的坐标
        self.rectangle1 = NULL#画布的矩形控件
        self.vertical = NULL#画布的矩形控件
        self.horizontal = NULL#画布的矩形控件
        self.YRadioVar = 1.0000#放大缩小Y比例值,用于单像素定位
        self.XRadioVar = 1.0000#放大缩小x比例值,用于单像素定位
        self.zoomRadioVar = 10#给opencv用于放大缩小的中间变量,此变量放大十倍,用时要/10
        self.Win_height = 700#窗口尺寸的初始值,用于调整窗口大小,而自动设定右边的选择栏
        self.Win_width = 1100#窗口尺寸的初始值,用于调整窗口大小,而自动设定右边的选择栏
        self.Win_heightbuffer = 700#窗口尺寸的缓冲,用于调整窗口大小,而自动设定右边的选择栏
        self.Win_widthbuffer = 1100#窗口尺寸的缓冲,用于调整窗口大小,而自动设定右边的选择栏
        self.YSetRadioVar = 1.0000#用户设置的坐标放大缩小,影响最终的坐标输出
        self.XSetRadioVar = 1.0000#用户设置的坐标放大缩小,影响最终的坐标输出
        self.screenshotpath = NULL#截图输出路径
        self.Coordinateoutputpath = NULL#坐标输出路径
        self.CoordinateoutputstatusFlag = NULL#截图输出路径
        self.excelrow = 0;
        # 图片转换窗口引用
        self.converter_window = None
    def Canvasline(self,event,x1,y1,radioup,radioxleft):
        if LargeCursor_Sel.get():
            # 计算十字光标颜色
            if self.G > 125: 
                R,G,B = 0xFF,0,0xFF
            else :
                R,G,B = 0,0xFF,0
            r_inv = format(R,'02x')
            g_inv = format(G,'02x')
            b_inv = format(B,'02x')
            self.px = '#'+r_inv+g_inv+b_inv
            #print(self.px )
            canvas.delete(self.horizontal)  #删除原来的
            canvas.delete(self.vertical)  #删除原来的
            #if event.x<=self.width+2 and event.y<=self.high+2:
            #self.horizontal = canvas.create_line(0, y1,self.Win_width,y1, fill = self.px)
            #self.vertical = canvas.create_line(x1, 0,x1,self.Win_height, fill = self.px)
            X0 = ((event.x+self.width * radioxleft) -2)-self.Win_widthbuffer
            Y0 =  ((event.y + self.high * radioup)-2)
            X1 = ((event.x+self.width * radioxleft) -2)+self.Win_widthbuffer
            Y1 =  ((event.y + self.high * radioup)-2)
            self.horizontal = canvas.create_line(X0,Y0,X1,Y1, fill = self.px)
            X0 = ((event.x+self.width * radioxleft) -2)
            Y0 =  ((event.y + self.high * radioup)-2)-self.Win_heightbuffer
            X1 = ((event.x+self.width * radioxleft) -2)
            Y1 =  ((event.y + self.high * radioup)-2)+self.Win_heightbuffer
            self.vertical = canvas.create_line(X0, Y0,X1,Y1, fill = self.px)
            #print(event.x,event.y)
        return;
    def Coordinate_Limit(self):
        if self.Current_x<0 :
            self.Current_x = 0;
        if self.Current_y <0:
            self.Current_y = 0;

        if self.Current_x >= self.width-1 :
            self.Current_x = self.width-1;
        if self.Current_y >= self.high-1:
            self.Current_y = self.high-1;
        #数值限位
        if self.Start_x<0 :
            self.Start_x = 0;
        if self.Start_y <0:
            self.Start_y = 0;

        if self.Start_x >= self.width :
            self.Start_x = self.width-1;
        if self.Start_y >= self.high:
            self.Start_y = self.high-1;
        #数值限位
        if self.End_x<0 :
            self.End_x = 0;
        if self.End_y <0:
            self.End_y = 0;

        if self.End_x >= self.width :
            self.End_x = self.width-1;
        if self.End_y >= self.high:
            self.End_y = self.high-1;

        #像素不能是单的,不然会对不上
        if (self.high%2) != 0:
            self.high = self.high-1
        if (self.width%2) != 0:
            self.width = self.width-1
        return;
    def MotionEvent(self,event):#鼠标移动事件
        radioup , raduodown = vertibar.get() #获取竖向滚动条的值
        radioxleft , radioxright = horibar.get()#获取横向滚动条的值
        self.Current_x,self.Current_y = ((event.x+self.width * radioxleft) -2), ((event.y + self.high * radioup)-2)#获取鼠标当前相对于窗口的值,左上画布开始为2,2,所以要减掉
        #canvas.create_oval(x1 , y1, x2, y2, fill = "red")
        #数值限位
        self.Coordinate_Limit();
        #print(event.x,event.y)
        self.R,self.G,self.B = self.image.getpixel((self.Current_x,self.Current_y))
        if RGB888Flag.get() == 1:
            self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
        else :
            self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
        result = str(int(self.Current_x*self.XRadioVar))+','+str(int(self.Current_y*self.YRadioVar))+'('+self.px+')'#将数字转成字符串
        Current_Coordinate.set(str(result))#将字符串输出到entry控件中
        self.Canvasline(event,self.Current_x,self.Current_y,radioup,radioxleft)    
    def Mouse_Left_dowm(self,event):
        radioup , raduodown = vertibar.get() #获取竖向滚动条的值
        radioxleft , radioxright = horibar.get()#获取横向滚动条的值
        self.Start_x,self.Start_y = ((event.x+self.width * radioxleft) -2), ((event.y + self.high * radioup)-2)#获取鼠标当前相对于窗口的值,左上画布开始为2,2,所以要减掉
        
        #canvas.create_oval(x1 , y1, x2, y2, fill = "red")
        
        self.Coordinate_Limit();
        
        self.R,self.G,self.B = self.image.getpixel((self.Start_x,self.Start_y))
        self.Canvasline(event,self.Start_x,self.Start_y,radioup,radioxleft)  
        if RGB888Flag.get() == 1:
            self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
        else :
            self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
        result = str(int(self.Start_x*self.XRadioVar))+','+str(int(self.Start_y*self.YRadioVar))+'('+self.px+')'#将数字转成字符串
        Current_Coordinate.set(str(result))#将字符串输出到entry控件中

        if User_Sel.get() == self.单点坐标 or User_Sel.get() == self.自动获取:
            result = str(int(self.Start_x*self.XRadioVar))+','+str(int(self.Start_y*self.YRadioVar))
            Coordinate.set(str(result))#将字符串输出到entry控件中
            self.CoordinateoutputstatusFlag = self.单点坐标
            if Copy_Sel.get() == 1:#判断用户是否需要自动拷贝
                pyperclip.copy(result)#拷贝到粘贴板中,此时用户只要直接CTRL+V就行
        elif User_Sel.get() == self.像素颜色 :#判断用户是否选择了像素颜色
            if self.Start_x<self.width and self.Start_y<self.high:
                #canvas.src_strlist = canvas.imagecolor.load()
                #self.R,self.G,self.B = canvas.src_strlist[self.Start_x, self.Start_y]
                if RGB888Flag.get() == 1:
                    self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
                else :
                    self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
                Coordinate.set(self.px)
                self.CoordinateoutputstatusFlag = self.像素颜色
                if Copy_Sel.get() == 1:#判断用户是否需要自动拷贝
                    pyperclip.copy(self.px)#拷贝到粘贴板中,此时用户只要直接CTRL+V就行
        return
    def Mouse_Middle_dowm(self,event):
        radioup , raduodown = vertibar.get() #获取竖向滚动条的值
        radioxleft , radioxright = horibar.get()#获取横向滚动条,左右的值
        self.Start_x,self.Start_y = ((event.x+self.width * radioxleft)-2), ((event.y + self.high * radioup)-2)#获取鼠标当前相对于窗口的值,左上画布开始为2,2,所以要减掉
        #canvas.create_oval(x1 , y1, x2, y2, fill = "red")
        self.Coordinate_Limit();
        
        self.R,self.G,self.B = self.image.getpixel((self.Start_x,self.Start_y))
        self.Canvasline(event,self.Start_x,self.Start_y,radioup,radioxleft)  
        if RGB888Flag.get() == 1:
            self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
        else :
            self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
        
        #鼠标当前位置更新
        self.Current_x,self.Current_y = self.Start_x,self.Start_y#将鼠标当前位置赋值
        result = str(int(self.Current_x*self.XRadioVar))+','+str(int(self.Current_y*self.YRadioVar))+'('+self.px+')'#将数字转成字符串
        Current_Coordinate.set(str(result))#将字符串输出到entry控件中
        if self.Start_x<self.width and self.Start_y<self.high:
            if RGB888Flag.get() == 1:
                self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
            else :
                self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
            Coordinate.set(self.px)#将字符串输出到entry控件中
            if Copy_Sel.get() == 1:#判断用户是否需要自动拷贝
                pyperclip.copy(self.px)#拷贝到粘贴板中,此时用户只要直接CTRL+V就行
            self.CoordinateoutputstatusFlag = self.像素颜色
        return

    def Mouse_RIGHT_dowm(self,event):
        radioup , raduodown = vertibar.get() #获取竖向滚动条的值
        radioxleft , radioxright = horibar.get()#获取横向滚动条,左右的值
        self.Start_x,self.Start_y = ((event.x+self.width * radioxleft)-2 ), ((event.y + self.high * radioup)-2)#获取鼠标当前相对于窗口的值,左上画布开始为2,2,所以要减掉
        #canvas.create_oval(x1 , y1, x2, y2, fill = "red")
        self.Coordinate_Limit();
        
        self.R,self.G,self.B = self.image.getpixel((self.Start_x,self.Start_y))
        self.Canvasline(event,self.Start_x,self.Start_y,radioup,radioxleft)  
        if RGB888Flag.get() == 1:
            self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
        else :
            self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
        
        #鼠标当前位置更新
        self.Current_x,self.Current_y = self.Start_x,self.Start_y#将鼠标当前位置赋值
        result = str(int(self.Current_x*self.XRadioVar))+','+str(int(self.Current_y*self.YRadioVar))+'('+self.px+')'#将数字转成字符串
        Coordinate.set(str(result))#将字符串输出到entry控件中
        Current_Coordinate.set(str(result))#将字符串输出到entry控件中
        self.CoordinateoutputstatusFlag = self.单点坐标
        return
    def B1MotionEvent(self,event):
        radioup , raduodown = vertibar.get() #获取竖向滚动条的值
        radioxleft , radioxright = horibar.get()#获取横向滚动条,左右的值
        #self.End_x,self.End_y = ((canvas.canvasx(event.x)+self.width * radioxleft)-2 ), ((canvas.canvasx(event.y) + self.high * radioup)-2) #-2才是对上像素
        self.End_x,self.End_y = ((event.x+self.width * radioxleft)-2 ), ((event.y + self.high * radioup)-2) #获取鼠标当前相对于窗口的值,左上画布开始为2,2,所以要减掉
        #canvas.delete(tk.ALL)

        
        self.Coordinate_Limit();
        canvas.delete(self.rectangle1)  #删除原来的红色矩形框
        self.rectangle1 = canvas.create_rectangle(self.Start_x, self.Start_y , self.End_x , self.End_y , outline = "red")#创建一个新的红色矩形框
        self.R,self.G,self.B = self.image.getpixel((self.End_x,self.End_y))
        if RGB888Flag.get() == 1:
            self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
        else :
            self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
        
        #鼠标当前位置更新
        self.Current_x,self.Current_y = self.End_x,self.End_y#将鼠标当前位置赋值
        result = str(int(self.Current_x*self.XRadioVar))+','+str(int(self.Current_y*self.YRadioVar))+'('+self.px+')'#将数字转成字符串
        Current_Coordinate.set(str(result))#在entry控件显示
        
        if User_Sel.get() == self.矩形坐标 or User_Sel.get() == self.自动获取:
            result = str(int(self.Start_x*self.XRadioVar))+','+str(int(self.Start_y*self.YRadioVar))+','+str(int(self.End_x*self.XRadioVar))+','+str(int(self.End_y*self.YRadioVar))
            Coordinate.set(str(result))#将字符串输出到entry控件中
            self.CoordinateoutputstatusFlag = self.矩形坐标
            if Copy_Sel.get() == 1:#判断用户是否需要自动拷贝
                pyperclip.copy(result)#拷贝到粘贴板中,此时用户只要直接CTRL+V就行
        # elif User_Sel.get() == self.截图输出:
        #     #cv_img = cv.imdecode(np.fromfile(self.get_fp, dtype=np.uint8), cv.IMREAD_COLOR)
        #     #cv_img = cv.imread("./0_backCartoon.jpg")
        #     #cropImg = self.image[self.Start_y:self.End_y,self.Start_x:self.End_x]   #裁剪图像
        #     #cv.imwrite(dest,cropImg)  #写入图像路径
        #     #cv.imencode('.jpg',cropImg)[1].tofile(self.screenshotpath)
        #     img = Image.open(self.get_fp)   # 读取图片
        #     a = (self.Start_x, self.Start_y , self.End_x , self.End_y)
        #     img = img.crop(a)
        #     img.save("C:/Users/Administrator/Desktop/666.bmp")   # 存储图片
        #     print("ok")
             
        elif User_Sel.get() == self.贴图坐标:
            result = str(int(self.Start_x*self.XRadioVar))+','+str(int(self.Start_y*self.YRadioVar))+','+str(int(self.End_x*self.XRadioVar))+','+str(int(self.End_y*self.YRadioVar))+','+str(int(self.Start_x*self.XRadioVar))+','+str(int(self.Start_y*self.YRadioVar))
            Coordinate.set(str(result))#将字符串输出到entry控件中
            self.CoordinateoutputstatusFlag = self.贴图坐标
            if Copy_Sel.get() == 1:#判断用户是否需要自动拷贝
                pyperclip.copy(result)#拷贝到粘贴板中,此时用户只要直接CTRL+V就行
        self.Canvasline(event,self.End_x,self.End_y,radioup,radioxleft)   
        return
    def B3MotionEvent(self,event):
        radioup , raduodown = vertibar.get() #获取竖向滚动条的值
        radioxleft , radioxright = horibar.get()#获取横向滚动条,左右的值
        #self.End_x,self.End_y = ((canvas.canvasx(event.x)+self.width * radioxleft)-2 ), ((canvas.canvasx(event.y) + self.high * radioup)-2) #-2才是对上像素
        self.End_x,self.End_y = ((event.x+self.width * radioxleft)-2 ), ((event.y + self.high * radioup)-2) #获取鼠标当前相对于窗口的值,左上画布开始为2,2,所以要减掉
        
        self.Coordinate_Limit();
        canvas.delete(self.rectangle1)  #删除原来的红色矩形框
        self.rectangle1 = canvas.create_rectangle(self.Start_x, self.Start_y , self.End_x , self.End_y , outline = "red")#创建一个新的红色矩形框
        
        self.R,self.G,self.B = self.image.getpixel((self.End_x,self.End_y))
        if RGB888Flag.get() == 1:
            self.px = str(hex((self.R<<16) | (self.G<<8)| self.B))
        else :
            self.px = str(hex((self.R>>3)<<11 | (self.G>>2)<<5 | self.B>>3))
        
        #鼠标当前位置更新
        self.Current_x,self.Current_y = self.End_x,self.End_y#将鼠标当前位置赋值
        result = str(int(self.Current_x*self.XRadioVar))+','+str(int(self.Current_y*self.YRadioVar))+'('+self.px+')'#将数字转成字符串
        Current_Coordinate.set(str(result))#在entry控件显示
        #重新计算一个需要停留显示的坐标
        result = str(int(self.Start_x*self.XRadioVar))+','+str(int(self.Start_y*self.YRadioVar))+','+str(int(self.End_x*self.XRadioVar))+','+str(int(self.End_y*self.YRadioVar))+','+str(int(self.Start_x*self.XRadioVar))+','+str(int(self.Start_y*self.YRadioVar))
        Coordinate.set(str(result))#将字符串输出到entry控件中
        if Copy_Sel.get() == 1:#判断用户是否需要自动拷贝
            pyperclip.copy(result)#拷贝到粘贴板中,此时用户只要直接CTRL+V就行
        self.Canvasline(event,self.End_x,self.End_y,radioup,radioxleft)  
        self.CoordinateoutputstatusFlag = self.贴图坐标
        return
    def zoomin_Picture(self,event):#图片放大
        image1 = self.image#先保存,用于有异常时恢复
        RadioVar = self.zoomRadioVar#先保存,用于有异常时恢复
        try:  # 捕获异常
            #self.image = Image.open(self.get_fp)
            self.image = cv.imdecode(np.fromfile(self.get_fp,dtype = np.uint8),-1)#opencv图片解码
            if self.zoomRadioVar <100:#限制幅度,以免溢出,这个程序只是简单的把图片放大了,对运行内存要求高,可能会造成卡顿
                self.zoomRadioVar = self.zoomRadioVar+1
        
            #self.image = self.image.resize((int(self.image.size[0]/self.zoomRadioVar), int(self.image.size[1]/self.zoomRadioVar)), 3 )# Image.LANCZOS) Resampling.
            self.image = cv.resize(self.image ,(0,0),fx = (self.zoomRadioVar/10), fy = (self.zoomRadioVar/10), interpolation = cv.INTER_AREA )#重新生成放大的图片
            #elif self.zoomRadioVar>3 and self.zoomRadioVar<=10:
            #    self.zoomRadioVar = self.zoomRadioVar-1
            #resized_image = ImageTk.Photoimage(self.image)
            #self.high = cv.height
            #self.width = cv.width 
            #Yradio1.set(self.XSetRadioVar)
            #Xradio1.set(self.YSetRadioVar)
            self.image = cv.cvtColor(self.image, cv.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA
            self.image = Image.fromarray(self.image)#将图像转换成Image对象
    
            self.high = self.image.height   #高度
            self.width = self.image.width  #宽度
            #print(self.width,self.high , self.zoomRadioVar)
            
            self.Coordinate_Limit();


             
            canvas.img_avatar = ImageTk.PhotoImage(self.image)#转成TKinter用的
            self.image = self.image.convert('RGB')#转成rgb
            canvas.config(
                width=100,
                height=100,
                scrollregion=(0,0,self.width,self.high)  ) #配置画布,指定滚动范围
            #tk.canvasimage = canvas.create_image(float(self.width/2),float(self.high/2) , self.image=canvas.img_avatar )
            tk.canvasimage = canvas.create_image(self.width/2,self.high/2 , image=canvas.img_avatar ) #创建画布图片
            #canvas.after(image=photo)
            #canvas.configure(image = photo)
    
            canvas.itemconfig(tk.canvasimage, image=canvas.img_avatar)#修改画布设置
            canvas.update()#刷新画布
            result = str(int(Function.zoomRadioVar*10))+'%'
            Multiplystr.set(result)
        except OverflowError:  # 处理异常,复原
            self.zoomRadioVar = RadioVar
            self.image = image1
        self.XRadioVar = self.XSetRadioVar/(self.zoomRadioVar/10)
        self.YRadioVar = self.YSetRadioVar/(self.zoomRadioVar/10)


        return
    def zoomout_Picture(self,event):
        image1 = self.image#先保存,用于有异常时恢复
        RadioVar = self.zoomRadioVar
        try:  # 捕获异常
            self.image = cv.imdecode(np.fromfile(self.get_fp,dtype = np.uint8),-1)#opencv图片解码
            if self.zoomRadioVar>1:
                self.zoomRadioVar = self.zoomRadioVar-1
            #elif self.zoomRadioVar>=3  and self.zoomRadioVar<10:
            #   self.zoomRadioVar = self.zoomRadioVar+1
            self.image = cv.resize(self.image ,(0,0),fx = (self.zoomRadioVar/10), fy = (self.zoomRadioVar/10), interpolation = cv.INTER_AREA )#重新生成放大的图片
           
            self.image = cv.cvtColor(self.image, cv.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA
            self.image = Image.fromarray(self.image)#将图像转换成Image对象
        
            self.high = self.image.height   #高度
            self.width = self.image.width  #宽度
                #print(self.width,self.high , self.zoomRadioVar)
            self.Coordinate_Limit();
            canvas.img_avatar = ImageTk.PhotoImage(self.image)#转成TKinter用的
            self.image = self.image.convert('RGB')#转成rgb
            canvas.config(
                    width=100,
                    height=100,
                    scrollregion=(0,0,self.width,self.high)  )   #配置画布,指定滚动范围
            #tk.canvasimage = canvas.create_image(float(self.width/2),float(self.high/2) , image=canvas.img_avatar )
            tk.canvasimage = canvas.create_image(self.width/2,self.high/2 , image=canvas.img_avatar ) #创建画布图片,设置放置图片的一半
            #canvas.after(image=photo)
            #canvas.configure(image = photo)
        
            canvas.itemconfig(tk.canvasimage, image=canvas.img_avatar)#修改画布设置
            canvas.update()#刷新画布
            result = str(int(Function.zoomRadioVar*10))+'%'
            Multiplystr.set(result)
        except cv.error:  # 处理异常
            self.zoomRadioVar = RadioVar
            self.image = image1    
        self.XRadioVar = self.XSetRadioVar/(self.zoomRadioVar/10)
        self.YRadioVar = self.YSetRadioVar/(self.zoomRadioVar/10)
        return

    def onMouseWheel(self,event):
        if event.delta>0:
            self.zoomin_Picture(event)
        else :
            self.zoomout_Picture(event)
    def OpenPicture(self,event):
        fp = self.get_fp
        #canvas.delete(tk.canvasimage)
        try:  # 捕获异常
            self.get_fp = filedialog.askopenfilename(filetypes = [("*",".*"),("BMP",".bmp"),("JPG",".jpg"),("PNG",".png"), ("GIF",".gif")])#打开文件,默认不限定格式
            self.image = cv.imdecode(np.fromfile(self.get_fp,dtype = np.uint8),-1)#opencv图片解码
            ws.title('ImageToolsV3.0 技术支持与合作QQ:1257784610     '+str(self.get_fp))
            #获取图片像素点大小
            #canvas.delete("all")

            self.image = cv.resize(self.image ,(0,0),fx = (self.zoomRadioVar/10), fy = (self.zoomRadioVar/10), interpolation = cv.INTER_AREA )#重新生成图片
            self.image = cv.cvtColor(self.image, cv.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA
            self.image = Image.fromarray(self.image)#将图像转换成Image对象
            #resized_image = ImageTk.Photoimage(self.image)
            self.high = self.image.height
            self.width = self.image.width 
            print(Function.high,Function.width)
            #print(self.high,self.width)
            self.Coordinate_Limit();
            canvas.img_avatar = ImageTk.PhotoImage(self.image)#转成TKinter用的
            #canvas.imagecolor = self.image.convert('RGB')
            self.image = self.image.convert('RGB')
            canvas.config(
                width=100,
                height=100,
           scrollregion=(0,0,self.width,self.high)#配置画布,指定滚动范围
               )   
            tk.canvasimage = canvas.create_image(float(self.width/2),float(self.high/2) , image=canvas.img_avatar )#创建画布图片,设置放置图片的一半
            #canvas.after(image=photo)
            #canvas.configure(image = photo)
        
            canvas.itemconfig(tk.canvasimage, image=canvas.img_avatar)#修改画布设置
            canvas.update()#刷新画布
        except AttributeError:  # 处理异常
            self.get_fp =fp
        except FileNotFoundError:  # 处理异常
            self.get_fp =fp 
        return

    def XYRadio_Set(self):
        self.XSetRadioVar = float(X_Radio.get())#读取控件输入的数值
        self.YSetRadioVar = float(Y_Radio.get())#读取控件输入的数值
        self.XRadioVar , self.YRadioVar = self.XSetRadioVar/(self.zoomRadioVar/10),self.YSetRadioVar/(self.zoomRadioVar/10)#设置输出的坐标
        return
    def adjust_windows(self,event):
        if (self.Win_heightbuffer !=ws.winfo_height()) or (self.Win_widthbuffer !=ws.winfo_width()):
            self.Win_heightbuffer , self.Win_widthbuffer = ws.winfo_height() , ws.winfo_width()
            pw1.update()#先刷新,不然下面的会执行失败
            pw1.sash_place(0,int(ws.winfo_width()-200),0)#放置中间的空间分割线
            #heightRadio , widthRadio= ws.winfo_height()/Win_height , ws.winfo_width()/Win_width
            #print(event.type)
            #print(event.widget)
    def Reset_Picture(self,event):
        self.image = cv.imdecode(np.fromfile(self.get_fp,dtype = np.uint8),-1)
        self.zoomRadioVar = 10
        self.XSetRadioVar = 1.0
        self.YSetRadioVar = 1.0
        self.XRadioVar = self.XSetRadioVar/(self.zoomRadioVar/10)
        self.YRadioVar = self.YSetRadioVar/(self.zoomRadioVar/10)
        
        '''interpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式,有以下几种:
        INTER_NEAREST - 最邻近插值
        INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
        INTER_AREA - resampling using pixel area relation. It may be a preferred method for self.image decimation, as it gives moire’-free results. But when the self.image is zoomed, it is similar to the INTER_NEAREST method.
        INTER_CUBIC - 4x4像素邻域内的双立方插值
        INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值
        ————————————————
        版权声明:本文为CSDN博主「xidaoliang123」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
        原文链接:https://blog.csdn.net/xidaoliang/article/details/86504720'''
        self.image = cv.resize(self.image ,(0,0),fx = (self.zoomRadioVar/10), fy = (self.zoomRadioVar/10), interpolation = cv.INTER_AREA )
        #resized_image = ImageTk.Photoimage(self.image)
        self.image = cv.cvtColor(self.image, cv.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA
        self.image = Image.fromarray(self.image)#将图像转换成Image对象
    
        self.high = self.image.height
        self.width = self.image.width 
        Yradio1.set(self.XSetRadioVar)
        Xradio1.set(self.YSetRadioVar)
        self.Coordinate_Limit();


    
        canvas.img_avatar = ImageTk.PhotoImage(self.image)#转成TKinter用的
        self.image = self.image.convert('RGB')#转成rgb
        canvas.config(
            width=100,
            height=100,
           scrollregion=(0,0,self.width,self.high) )   #配置画布,指定滚动范围
        tk.canvasimage = canvas.create_image(float(self.width/2),float(self.high/2) , image=canvas.img_avatar ) #创建画布图片,设置放置图片的一半
        #canvas.after(image=photo)
        #canvas.configure(image = photo)
    
        canvas.itemconfig(tk.canvasimage, image=canvas.img_avatar)#修改画布设置
        canvas.update()#刷新画布
        result = str(int(Function.zoomRadioVar*10))+'%'
        Multiplystr.set(result)
        return
    def Getscreenshot_outputpath(self,event):
        #self.screenshotpath = filedialog.askdirectory()#获取目录
        self.screenshotpath = filedialog.asksaveasfilename(initialfile='截图',filetypes=[("BMP",".bmp"),("JPG",".jpg"),("PNG",".png"),("TIF",".tif")], defaultextension='.bmp')#获取保存文件
        if self.screenshotpath :#用户选择了文件
            #print(int(self.Start_y),int(self.End_y),int(self.Start_x),int(self.End_x))
            img = cv.imdecode(np.fromfile(self.get_fp,dtype = np.uint8),cv.IMREAD_COLOR)#opencv图片解码,重新打开一个来截图,避免图片失真
            #截图,由于前面将self.XRadioVar和xy系数绑定了,这里直接用zoomRadioVar来反算原来的xy坐标,保持输出的和矩形圈住的是一样的
            cropImg = img[int(self.Start_y/(self.zoomRadioVar/10)):int(self.End_y/(self.zoomRadioVar/10)),int(self.Start_x/(self.zoomRadioVar/10)):int(self.End_x/(self.zoomRadioVar/10))]     # 裁剪【y1,y2:x1,x2】
            
            #print(self.screenshotpath)
            cv.imencode(os.path.splitext(self.screenshotpath)[1], cropImg)[1].tofile(self.screenshotpath) #输出
            
        else :#用户没有选择文件跳出
            return
    def SaveCoordinate_output(self,event):
        #self.screenshotpath = filedialog.askdirectory()#获取目录
        if self.Coordinateoutputpath == NULL:
            self.Coordinateoutputpath = filedialog.asksaveasfilename(initialfile='Coordinatesavefile',filetypes=[("XLSX",".xlsx")],defaultextension='.xlsx')#获取保存文件
        if self.Coordinateoutputpath :#用户选择了文件
            
            # 数据可以是单个值、列表、行或字典等
            try:
                # 尝试加载已存在的Excel文件
                excelwb = opxl.load_workbook(self.Coordinateoutputpath)
                
            except FileNotFoundError:
                excelwb = opxl.Workbook()
                
            #if self.CoordinateoutputstatusFlag == self.单点坐标:
            #    print(self.Start_x,self.Start_y)
            data =  [int(self.Start_x*self.XRadioVar),int(self.Start_y*self.YRadioVar)],
                
            sheet = excelwb.active
            #for i,value in enumerate(data):
            #    sheet.cell(row = self.excelrow,column= i+1).value = value
            for row in data:
                sheet.append(row)
            # 保存工作簿到文件
            excelwb.save(self.Coordinateoutputpath)
            excelwb.close()
            CoordinateButton.config(text = "保存到下一行(S)")
        else :#用户没有选择文件跳出
            return
    def canvasFocusOut(self,event):
        if self.vertical!= NULL:
            canvas.delete(self.vertical)
        if self.horizontal!=NULL:
            canvas.delete(self.horizontal)
        return
    def canvasFocusIn(self,event):
        #print("out")
        '''if self.vertical!= NULL:
            canvas.delete(self.vertical)
        if self.horizontal!=NULL:
            canvas.delete(self.horizontal)'''
        return
    def ImageSwitchapp(self,root):
        """打开图片转换窗口"""
        if self.converter_window is not None and self.converter_window.winfo_exists():
            self.converter_window.lift()
            return
            
        self.converter_window = tk.Toplevel(self.root)
        self.converter_window.title("图片转换 技术支持与合作QQ:1257784610")
        self.converter_window.geometry("600x550")
        
        # 防止同时打开多个转换窗口
        self.converter_window.protocol("WM_DELETE_WINDOW", self.on_converter_close)
        
        # 转换窗口内容
        converter_frame = ttk.Frame(self.converter_window, padding="10")
        converter_frame.pack(fill=tk.BOTH, expand=True)

    # 设置支持的格式
        self.supported_formats = {
            "BMP": "bmp",
            "PNG": "png",
            "JPEG": "jpg",
            "GIF": "gif",
            "TIFF": "tiff",
            "WEBP": "webp"
        }
        
        # 输入文件路径
        self.input_frame = LabelFrame(self.converter_window, text="输入设置", padx=10, pady=10)
        self.input_frame.pack(pady=10, padx=10, fill="x")
        
        # 文件选择按钮
        self.file_buttons_frame = Frame(self.input_frame)
        self.file_buttons_frame.pack(fill="x", pady=(0, 5))
        
        self.add_files_button = Button(self.file_buttons_frame, text="添加文件", command=self.select_input_files)
        self.add_files_button.pack(side=LEFT, padx=(0, 5))
        
        self.add_folder_button = Button(self.file_buttons_frame, text="添加文件夹", command=self.select_input_folder)
        self.add_folder_button.pack(side=LEFT, padx=(0, 5))
        
        self.clear_button = Button(self.file_buttons_frame, text="清空列表", command=self.clear_input_list)
        self.clear_button.pack(side=LEFT)
        
        # 文件列表
        self.listbox_frame = Frame(self.input_frame)
        self.listbox_frame.pack(fill="both", expand=True)
        
        self.scrollbar = Scrollbar(self.listbox_frame)
        self.scrollbar.pack(side=RIGHT, fill=Y)
        
        self.input_listbox = Listbox(
            self.listbox_frame, 
            width=70, 
            height=8, 
            selectmode=MULTIPLE,
            yscrollcommand=self.scrollbar.set
        )
        self.input_listbox.pack(fill="both", expand=True)
        self.scrollbar.config(command=self.input_listbox.yview)
        
        # 输出设置
        self.output_frame = LabelFrame(self.converter_window, text="输出设置", padx=10, pady=10)
        self.output_frame.pack(pady=10, padx=10, fill="x")
        
        self.output_label = Label(self.output_frame, text="输出文件夹:")
        self.output_label.grid(row=0, column=0, padx=(0, 5), sticky="w")
        
        self.output_entry = Entry(self.output_frame, width=50)
        self.output_entry.grid(row=0, column=1, padx=(0, 5))
        
        self.output_button = Button(self.output_frame, text="选择文件夹", command=self.select_output_folder)
        self.output_button.grid(row=0, column=2)
        
        # 格式选择
        self.format_frame = LabelFrame(self.converter_window, text="转换设置", padx=10, pady=10)
        self.format_frame.pack(pady=10, padx=10, fill="x")
        
        self.format_label = Label(self.format_frame, text="目标格式:")
        self.format_label.grid(row=0, column=0, padx=(0, 5), sticky="w")
        
        self.format_var = StringVar()
        self.format_var.set("PNG")
        self.format_menu = OptionMenu(self.format_frame, self.format_var, *self.supported_formats.keys())
        self.format_menu.grid(row=0, column=1, sticky="w")
        
        # 保持原始文件名
        self.keep_name_var = IntVar(value=1)
        self.keep_name_check = Checkbutton(
            self.format_frame, 
            text="保持原始文件名", 
            variable=self.keep_name_var
        )
        self.keep_name_check.grid(row=0, column=2, padx=(20, 0))
        
        # 进度条
        self.progress_frame = Frame(self.converter_window)
        self.progress_frame.pack(pady=(0, 10), padx=10, fill="x")
        
        self.progress_label = Label(self.progress_frame, text="准备就绪")
        self.progress_label.pack(anchor="w")
        
        self.progress = ttk.Progressbar(self.progress_frame, orient=HORIZONTAL, length=600, mode='determinate')
        self.progress.pack(fill="x")
        
        # 转换按钮
        self.button_frame = Frame(self.converter_window)
        self.button_frame.pack(pady=(0, 10))
        
        self.convert_button = Button(
            self.button_frame, 
            text="开始转换", 
            command=self.start_conversion, 
            bg="#4CAF50", 
            fg="white", 
            state=DISABLED,
            width=15
        )
        self.convert_button.pack(side=LEFT, padx=5)
        
        self.cancel_button = Button(
            self.button_frame, 
            text="取消", 
            command=self.cancel_conversion, 
            bg="#f44336", 
            fg="white",
            width=15,
            state=DISABLED
        )
        self.cancel_button.pack(side=LEFT, padx=5)
        
        # 状态标签
        self.status_label = Label(self.converter_window, text="", fg="blue", wraplength=600, justify="left")
        self.status_label.pack(pady=(0, 10))
        
        # 转换线程控制
        self.conversion_running = False
        self.conversion_thread = None
    
    def select_input_files(self):
        file_paths = filedialog.askopenfilenames(
            title="选择图片文件",
            filetypes=[("图片文件", "*.gif;*.png;*.jpg;*.jpeg;*.bmp;*.tiff;*.webp"), ("所有文件", "*.*")]
        )
        if file_paths:
            self.add_files_to_list(file_paths)
    
    def select_input_folder(self):
        folder_path = filedialog.askdirectory(title="选择图片文件夹")
        if folder_path:
            # 获取文件夹中所有支持的图片文件
            supported_extensions = [f".{ext}" for ext in self.supported_formats.values()]
            file_paths = []
            for root_dir, _, files in os.walk(folder_path):
                for file in files:
                    if os.path.splitext(file)[1].lower() in supported_extensions:
                        file_paths.append(os.path.join(root_dir, file))
            
            if file_paths:
                self.add_files_to_list(file_paths)
            else:
                messagebox.showwarning("警告", "选择的文件夹中没有找到支持的图片文件!")
    
    def add_files_to_list(self, file_paths):
        for path in file_paths:
            if path not in self.input_listbox.get(0, END):
                self.input_listbox.insert(END, path)
        
        # 自动设置输出文件夹为第一个文件所在目录
        if not self.output_entry.get() and file_paths:
            output_dir = os.path.dirname(file_paths[0])
            self.output_entry.insert(0, output_dir)
        
        self.update_convert_button_state()
    
    def clear_input_list(self):
        self.input_listbox.delete(0, END)
        self.update_convert_button_state()
    
    def select_output_folder(self):
        folder_path = filedialog.askdirectory(title="选择输出文件夹")
        if folder_path:
            self.output_entry.delete(0, END)
            self.output_entry.insert(0, folder_path)
            self.update_convert_button_state()
    
    def update_convert_button_state(self):
        if self.input_listbox.size() > 0 and self.output_entry.get():
            self.convert_button.config(state=NORMAL)
        else:
            self.convert_button.config(state=DISABLED)
    
    def start_conversion(self):
        if self.conversion_running:
            return
            
        input_files = self.input_listbox.get(0, END)
        output_dir = self.output_entry.get()
        target_format = self.supported_formats[self.format_var.get()]
        keep_original_name = self.keep_name_var.get()
        
        if not input_files:
            tk.messagebox.showerror("错误", "请选择要转换的图片文件!")
            return
            
        if not os.path.isdir(output_dir):
            tk.messagebox.showerror("错误", "输出文件夹不存在!")
            return
            
        # 创建输出目录(如果不存在)
        os.makedirs(output_dir, exist_ok=True)
        
        # 设置UI状态
        self.conversion_running = True
        self.update_ui_during_conversion(True)
        
        # 启动转换线程
        self.conversion_thread = Thread(
            target=self.convert_images, 
            args=(input_files, output_dir, target_format, keep_original_name),
            daemon=True
        )
        self.conversion_thread.start()
    
    def convert_images(self, input_files, output_dir, target_format, keep_original_name):
        total_files = len(input_files)
        success_count = 0
        failed_files = []
        
        self.update_progress(f"准备转换 {total_files} 个文件...", 0, total_files)
        
        for i, input_path in enumerate(input_files, 1):
            if not self.conversion_running:
                break
                
            try:
                self.update_progress(f"正在转换 {i}/{total_files}: {os.path.basename(input_path)}", i, total_files)
                
                # 打开图片文件
                with Image.open(input_path) as img:
                    # 生成输出文件名
                    if keep_original_name:
                        filename = os.path.splitext(os.path.basename(input_path))[0]
                    else:
                        filename = f"converted_{i}"
                    
                    output_path = os.path.join(output_dir, f"{filename}.{target_format}")
                    
                    # 检查文件是否已存在
                    counter = 1
                    while os.path.exists(output_path):
                        output_path = os.path.join(output_dir, f"{filename}_{counter}.{target_format}")
                        counter += 1
                    
                    # 转换为RGB模式(对于不支持透明通道的格式)
                    if target_format.lower() in ["bmp", "jpg", "jpeg"] and img.mode in ["RGBA", "LA", "P"]:
                        img = img.convert("RGB")
                    
                    # 保存为目标格式
                    img.save(output_path, target_format.upper())
                    success_count += 1
                
            except Exception as e:
                failed_files.append((os.path.basename(input_path), str(e)))
                continue
        
        # 转换完成
        self.conversion_running = False
        self.converter_window.after(0, lambda: self.on_conversion_complete(success_count, total_files, failed_files))
    
    def update_progress(self, message, current=0, total=0):
        self.converter_window.after(0, lambda: self._update_progress_ui(message, current, total))
    
    def _update_progress_ui(self, message, current, total):
        self.progress_label.config(text=message)
        if total > 0:
            self.progress["maximum"] = total
            self.progress["value"] = current
        self.converter_window.update_idletasks()
    
    def on_conversion_complete(self, success_count, total_files, failed_files):
        # 恢复UI状态
        self.update_ui_during_conversion(False)
        
        # 显示结果
        result_message = f"转换完成! 成功 {success_count}/{total_files} 个文件"
        if failed_files:
            result_message += "\n\n失败文件:\n" + "\n".join([f"• {f[0]}: {f[1]}" for f in failed_files])
        
        self.status_label.config(
            text=result_message, 
            fg="green" if success_count == total_files else "orange"
        )
        
        if success_count > 0:
            tk.messagebox.showinfo("转换完成", result_message)
        else:
            tk.messagebox.showerror("转换失败", "所有文件转换失败!\n" + "\n".join([f[1] for f in failed_files]))
    
    def cancel_conversion(self):
        if self.conversion_running:
            if tk.messagebox.askyesno("确认", "确定要取消当前转换任务吗?"):
                self.conversion_running = False
                self.status_label.config(text="转换已取消", fg="red")
                self.progress_label.config(text="转换已取消")
    
    def update_ui_during_conversion(self, converting):
        if converting:
            self.convert_button.config(state=DISABLED)
            self.cancel_button.config(state=NORMAL)
            self.add_files_button.config(state=DISABLED)
            self.add_folder_button.config(state=DISABLED)
            self.clear_button.config(state=DISABLED)
            self.output_button.config(state=DISABLED)
        else:
            self.convert_button.config(state=NORMAL if self.input_listbox.size() > 0 and self.output_entry.get() else DISABLED)
            self.cancel_button.config(state=DISABLED)
            self.add_files_button.config(state=NORMAL)
            self.add_folder_button.config(state=NORMAL)
            self.clear_button.config(state=NORMAL)
            self.output_button.config(state=NORMAL)
    
    def on_closing(self):
        if self.conversion_running:
            if tk.messagebox.askokcancel("退出", "转换正在进行中,确定要退出吗?"):
                self.conversion_running = False
                if self.conversion_thread and self.conversion_thread.is_alive():
                    self.conversion_thread.join(timeout=1)
                self.converter_window.destroy()
        else:
            self.converter_window.destroy()

    def on_converter_close(self):
        """关闭转换窗口时的处理"""
        self.converter_window.destroy()
        self.converter_window = None
        return

ws = tk.Tk()
ws.title('ImageToolsV3.0 技术支持与合作QQ:1257784610')
ws.geometry('1100x700')
pw1=tk.PanedWindow(ws,orient=tk.HORIZONTAL,width = 900,height = 700,sashrelief='groove') # 创建横向分割面板

pw1.pack(fill=tk.BOTH,expand=True) # 尺寸扩展到整个窗体
frame = tk.Frame(pw1 ,width = 900,height = 700)
ws.update_idletasks()
##########################################测试用代码#######################################################
# print(time.time())
# print(datetime.datetime.now())
# print(datetime.datetime.now().year,datetime.datetime.now().month,datetime.datetime.now().day,datetime.datetime.now().hour,datetime.datetime.now().minute)
#软件时长测试,也许直接判断天数更好
# year = 2025
# month = 3
# day = 20
# if datetime.datetime.now().year>=year:
#     if datetime.datetime.now().month>month:
#         strdisplay = "Your two-year subscription is end.Please contact us(Wechat:Q2596238662/QQ:1257784610)to obtain the new software and avoid any interruption in service!!!"
#         tk.messagebox.showinfo(title = "License Expiry Notice",message=strdisplay)
#         sys.exit()
#     elif datetime.datetime.now().month>=month:
#         if datetime.datetime.now().day>=day:
#             strdisplay = "Your two-year subscription is end.Please contact us(Wechat:Q2596238662/QQ:1257784610)to obtain the new software and avoid any interruption in service!!!"
#             tk.messagebox.showinfo(title = "License Expiry Notice",message=strdisplay)
#             sys.exit()
#         else :
#             remainderday = day - datetime.datetime.now().day
#             strdisplay = "Your two-year subscription is ending in "+str(remainderday)+" days. Please contact us(Wechat:Q2596238662/QQ:1257784610)to obtain the new software and avoid any interruption in service."
#             tk.messagebox.showinfo(title = "License Expiry Notice",message=strdisplay)
#     elif datetime.datetime.now().month>=month-1:
#         remainderday = 30+day-datetime.datetime.now().day
#         strdisplay = "Your two-year subscription is ending in "+str(remainderday)+" days. Please contact us(Wechat:Q2596238662/QQ:1257784610)to obtain the new software and avoid any interruption in service."
#         tk.messagebox.showinfo(title = "License Expiry Notice",message=strdisplay)
##########################################测试用代码#######################################################
#软件时长测试,也许直接判断天数更好
# 获取当前日期
now = datetime.datetime.now()
 
# 创建一个结束的日期,如果想要永久把这段代码删掉
epoch = datetime.datetime(2027, 5, 10)

# 计算从1970年1月1日到当前日期的时间差
total_seconds = (epoch-now).total_seconds()

# 将总秒数转换为总天数
total_days = total_seconds / 86400
#print(total_days)
if total_days>0 and total_days<=31:
    strdisplay = "Your one-year subscription is ending in "+str(int(total_days))+" days. Please update software or contact us(Wechat:Q2596238662/QQ:1257784610)to obtain the new software and avoid any interruption in service."
    tk.messagebox.showinfo(title = "License Expiry Notice",message=strdisplay)
elif total_days <=0:
    strdisplay = "Your one-year subscription is end.Please update software or contact us(Wechat:Q2596238662/QQ:1257784610)to obtain the new software and avoid any interruption in service!!!"
    tk.messagebox.showinfo(title = "License Expiry Notice",message=strdisplay)
    sys.exit()
###################################################################################################
try:  # 捕获异常
    Function = Callback(ws)
    #Function.get_fp = filedialog.askopenfilename(filetypes = [("BMP",".bmp"),("JPG",".jpg"),("PNG",".png"), ("GIF",".gif")])
    Function.get_fp = filedialog.askopenfilename(filetypes = [("*",".*"),("BMP",".bmp"),("JPG",".jpg"),("PNG",".png"), ("GIF",".gif")])#打开文件,默认不限定格式
    ws.title('ImageToolsV3.0 技术支持与合作QQ:1257784610   '+str(Function.get_fp))
   #image = Image.open(get_fp)
    Function.image = cv.imdecode(np.fromfile(Function.get_fp,dtype = np.uint8),-1)
    Function.image = cv.cvtColor(Function.image, cv.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA
    Function.image = Image.fromarray(Function.image)#将图像转换成Image对象
    
    #获取图片像素点大小
    Function.high = Function.image.height   #高度
    Function.width = Function.image.width  #宽度
    #print(Function.high,Function.width)
    Function.Coordinate_Limit();
    canvas=tk.Canvas(
        frame,
    
        bg='#4A7A8C',
        width=900,
        height=700,
        cursor="tcross",
        scrollregion=(0,0,Function.width,Function.high)    
        )
    #canvas.imagecolor = image.convert('RGB')
    Function.image = Function.image.convert('RGB')#RGB模式
    Function.R,Function.G,Function.B = Function.image.getpixel((0,0))
    #canvas.src_strlist = canvas.imagecolor.load()
    #R,G,B = canvas.src_strlist[1, 1]
    
    Function.px = str(hex((Function.R>>3)<<11 | (Function.G>>2)<<5 | Function.B>>3))
    #垂直滑动条
    vertibar=tk.Scrollbar(
        frame,
        orient=tk.VERTICAL
        )
    vertibar.pack(side=tk.RIGHT,fill=tk.Y)
    vertibar.config(command=canvas.yview)
    #水平滑动条
    horibar=tk.Scrollbar(    
        frame,
        orient=tk.HORIZONTAL
        )
    horibar.pack(side=tk.BOTTOM,fill=tk.X)
    horibar.config(command=canvas.xview)
    canvas.config(
        xscrollcommand=horibar.set, 
        yscrollcommand=vertibar.set
        )#配置滑动条
    canvas.img_avatar  = ImageTk.PhotoImage(Function.image)
    #imgLabel = tk.Label(frame ,image = photo)
    #imgLabel.pack()
    tk.canvasimage = canvas.create_image(float(Function.width/2),float(Function.high/2) , image=canvas.img_avatar ) #此处加2是为了全部显示
    #Function.rectangle1 = canvas.create_rectangle(0, 0 , 1 , 1 , outline = "red")

    canvas.pack(expand=True,side=tk.LEFT,fill=tk.BOTH)
    #ws.protocol( "WM_TAKE_FOCUS" , adjust_windows);



    ####################################################
    User_Sel = tk.IntVar()
    User_Sel.set(5)
    Copy_Sel = tk.IntVar()
    Copy_Sel.set(1)
    LargeCursor_Sel = tk.IntVar()
    LargeCursor_Sel.set(1)
    RGB888Flag = tk.IntVar()
    RGB888Flag.set(0)
    Coordinate = tk.StringVar()
    Current_Coordinate = tk.StringVar()
    Xradio1 = tk.StringVar()
    Yradio1 = tk.StringVar()
    Multiplystr = tk.StringVar()
    result = str(int(Function.zoomRadioVar*10))+'%'
    
    pw2=tk.PanedWindow(pw1,orient=tk.VERTICAL,width = 200,height = 700,sashrelief='groove')
    pw2.pack() # 尺寸扩展到整个窗体
    frame1 = tk.Frame(pw2)
    frame2 = tk.Frame(pw2)
    textLabel = tk.Label(frame1  ,textvariable= Multiplystr )
    textLabel.pack(expand=False)
    Multiplystr.set(result)
    Coordinateout = tk.Entry(frame1 , width = 30 ,  text = Coordinate  , state = "readonly" , exportselection = 1)
    #Coordinateout.grid(column = 0 , row = 1)
    Coordinateout.pack()
    Current_Coordinate_out = tk.Entry(frame1 , width = 30 ,  text = Current_Coordinate  , state = "readonly" , exportselection = 1)
    Current_Coordinate_out.pack()
    
    LANGS= [("矩形坐标" , 1),
            ("贴图坐标" , 2),
            ("像素坐标" , 3),
            ("像素颜色" , 4),
            ("快捷获取" , 5)]
    for lang ,num in LANGS:
        b= tk.Radiobutton(frame2 , text = lang , variable = User_Sel , value = num )
        b.pack(fill =tk.X)
    Largecursorbutton = tk.Checkbutton(frame2 , text = "十字光标" , variable= LargeCursor_Sel)
    Largecursorbutton.pack()
    RGBModeButton = tk.Checkbutton(frame2 , text = "RGB888(565)" , variable= RGB888Flag)
    RGBModeButton.pack()
    
    
    Copybutton = tk.Checkbutton(frame2 , text = "自动复制到粘贴板" , variable= Copy_Sel)
    Copybutton.pack()
    OpenPictureButton = tk.Button(frame2 , text = "打开图片(O)"  , command = lambda:Function.OpenPicture(NULL),width = 12)
    OpenPictureButton.pack()
    screenshotpathButton = tk.Button(frame2 , text = "输出截图到(P)"  , command = lambda:Function.Getscreenshot_outputpath(NULL),width = 12)
    screenshotpathButton.pack()
    CoordinateButton = tk.Button(frame2 , text = "保存坐标到(S)"  , command = lambda:Function.SaveCoordinate_output(NULL),width = 12)
    CoordinateButton.pack()
    
    tk.Label(frame2 , text = '请输入X转换系数,默认为1').pack()

    X_Radio = tk.Entry(frame2 , width = 20 ,  textvariable = 1, text = Xradio1   , exportselection = 1)
    X_Radio.pack()
    Xradio1.set(1)
    tk.Label(frame2 , text = '请输入Y转换系数,默认为1').pack()

    Y_Radio = tk.Entry(frame2 , width = 20 ,  textvariable = 1,text = Yradio1   , exportselection = 1)
    Y_Radio.pack()
    Yradio1.set(1)
    SetxyButton = tk.Button(frame2 , text = "设置XY系数"  , command = Function.XYRadio_Set ,width = 12)
    SetxyButton.pack()

    zoominButton = tk.Button(frame2 , text = "图片放大(up)"  , command = lambda:Function.zoomin_Picture(NULL) ,width = 12)
    zoominButton.pack()
    zoomoutButton = tk.Button(frame2 , text = "图片缩小(dn)"  , command = lambda:Function.zoomout_Picture(NULL),width = 12)
    zoomoutButton.pack()
    ResetButton = tk.Button(frame2 , text = "图片复位(R)"  , command = lambda:Function.Reset_Picture(NULL),width = 12)
    ResetButton.pack()
    imageswitchButton = tk.Button(frame2 , text = "图片转换(T)"  , command = lambda:Function.ImageSwitchapp(NULL),width = 12)
    imageswitchButton.pack()
    #canvas.bind("<Configure>", adjust_windows)#适应窗口
    pw1.bind("<Configure>", Function.adjust_windows)#适应窗口
    #pw2.bind("<Configure>", adjust_windows)#适应窗口
    canvas.bind("<Motion>" , Function.MotionEvent)#鼠标移动事件
    canvas.bind("<B1-Motion>" , Function.B1MotionEvent)#鼠标左键按下并移动事件
    canvas.bind("<B3-Motion>" , Function.B3MotionEvent)#鼠标右键按下并移动事件
    canvas.bind("<Button-1>" , Function.Mouse_Left_dowm)#鼠标左键按下事件
    canvas.bind("<Button-3>" , Function.Mouse_RIGHT_dowm)#鼠标右键按下事件
    canvas.bind("<Button-2>" , Function.Mouse_Middle_dowm)#鼠标滚轮按下事件
    canvas.bind("<Control-MouseWheel>" , Function.onMouseWheel)#ctrl+鼠标滚轮事件
    canvas.bind("<Control-MouseWheel>" , Function.onMouseWheel)#ctrl+鼠标滚轮事件
    canvas.bind("<Leave>" , Function.canvasFocusOut)#画布失焦事件
    canvas.bind("<Enter>" , Function.canvasFocusIn)#鼠标进入画布聚焦事件
    #######################################################
    ws.bind('<KeyPress-s>', Function.SaveCoordinate_output)#s按键
    ws.bind('<KeyPress-S>', Function.SaveCoordinate_output)#S按键
    ws.bind('<KeyPress-p>', Function.Getscreenshot_outputpath)#p按键
    ws.bind('<KeyPress-P>', Function.Getscreenshot_outputpath)#P按键
    ws.bind('<KeyPress-o>', Function.OpenPicture)#o按键
    ws.bind('<KeyPress-O>', Function.OpenPicture)#O按键
    ws.bind('<KeyPress-r>', Function.Reset_Picture)#r按键
    ws.bind('<KeyPress-R>', Function.Reset_Picture)#R按键
    ws.bind('<KeyPress-Prior>', Function.zoomin_Picture)#pdup按键
    ws.bind('<KeyPress-Next>', Function.zoomout_Picture)#pddn按键
    ws.bind('<KeyPress-Up>', Function.zoomin_Picture)#方向↓按键
    ws.bind('<KeyPress-Down>', Function.zoomout_Picture)#方向⬆按键




    pw1.add(frame) # pw1加入fr1组件
    pw2.add(frame1) # pw2加入fr2组件
    pw2.add(frame2) # pw2加入fr3组件
    pw1.add(pw2) # pw1加入pw2组件

    ws.mainloop()
except FileNotFoundError:  
    sys.exit()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值