吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1903|回复: 6
收起左侧

[Python 原创] 图片坐标点取值工具python源码

[复制链接]
钱途迷茫 发表于 2025-5-31 15:00
本帖最后由 钱途迷茫 于 2025-5-31 15:12 编辑

前端页面经常需要对图片坐标点进行取值,之前都是打开windows自带的编辑图片工具一个个点查看坐标,效率太低,最近接触了python,于是配合上豆包,写了一个坐标取值工具,效率大大提升
支持点击图片任意位置选取坐标值,并复制到剪切板

技术有限,不知道如何打包成exe程序,有好心人可以帮忙打包一下

微信截图_20250531145852.jpg

[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import os


class ImageCoordinateTool:
    def __init__(self, root):
        self.root = root
        self.root.title("图片坐标点获取工具")
        self.root.geometry("800x600")

        # 设置中文字体支持
        self.root.option_add("*Font", "SimHei 10")

        self.image_path = None
        self.original_img = None
        self.photo_img = None
        self.scale_factor = 1.0

        # 创建界面
        self.create_widgets()

    def create_widgets(self):
        # 顶部工具栏
        top_frame = tk.Frame(self.root)
        top_frame.pack(fill=tk.X, padx=10, pady=10)

        # 打开图片按钮
        open_btn = tk.Button(top_frame, text="打开图片", command=self.open_image)
        open_btn.pack(side=tk.LEFT, padx=5)

        # 坐标显示框
        self.coord_label = tk.Label(top_frame, text="坐标: 0,0")
        self.coord_label.pack(side=tk.LEFT, padx=20)

        # 自动复制选项
        self.auto_copy_var = tk.BooleanVar(value=True)
        auto_copy_check = tk.Checkbutton(top_frame, text="自动复制坐标", variable=self.auto_copy_var)
        auto_copy_check.pack(side=tk.LEFT, padx=20)

        # 缩放控制
        zoom_frame = tk.Frame(top_frame)
        zoom_frame.pack(side=tk.RIGHT, padx=5)

        tk.Label(zoom_frame, text="缩放:").pack(side=tk.LEFT)
        self.zoom_in_btn = tk.Button(zoom_frame, text="+", command=self.zoom_in, width=3)
        self.zoom_in_btn.pack(side=tk.LEFT, padx=2)
        self.zoom_out_btn = tk.Button(zoom_frame, text="-", command=self.zoom_out, width=3)
        self.zoom_out_btn.pack(side=tk.LEFT, padx=2)

        # 重置视图按钮
        reset_btn = tk.Button(zoom_frame, text="重置", command=self.reset_view, width=5)
        reset_btn.pack(side=tk.LEFT, padx=2)

        # 图片显示区域 - 使用带滚动条的框架
        self.canvas_frame = tk.Frame(self.root)
        self.canvas_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        # 创建垂直滚动条
        self.vscrollbar = tk.Scrollbar(self.canvas_frame, orient=tk.VERTICAL)
        self.vscrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 创建水平滚动条
        self.hscrollbar = tk.Scrollbar(self.canvas_frame, orient=tk.HORIZONTAL)
        self.hscrollbar.pack(side=tk.BOTTOM, fill=tk.X)

        # 创建画布
        self.canvas = tk.Canvas(self.canvas_frame, bg="white",
                                yscrollcommand=self.vscrollbar.set,
                                xscrollcommand=self.hscrollbar.set)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 配置滚动条
        self.vscrollbar.config(command=self.canvas.yview)
        self.hscrollbar.config(command=self.canvas.xview)

        # 绑定鼠标事件
        self.canvas.bind("<Motion>", self.on_mouse_move)
        self.canvas.bind("<Button-1>", self.on_click)

        # 绑定滚轮事件(跨平台)
        self.canvas.bind("<MouseWheel>", self.on_mouse_wheel)  # Windows
        self.canvas.bind("<Button-4>", self.on_mouse_wheel)  # Linux
        self.canvas.bind("<Button-5>", self.on_mouse_wheel)  # Linux

        # 状态栏
        self.status_bar = tk.Label(self.root, text="就绪", bd=1, relief=tk.SUNKEN, anchor=tk.W)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)

        # 坐标点列表
        self.points_frame = tk.Frame(self.root)
        self.points_frame.pack(fill=tk.X, padx=10, pady=5)

        tk.Label(self.points_frame, text="已选坐标点:").pack(side=tk.LEFT)

        self.points_listbox = tk.Listbox(self.points_frame, width=50, height=3)
        self.points_listbox.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

        copy_btn = tk.Button(self.points_frame, text="复制坐标", command=self.copy_coordinates)
        copy_btn.pack(side=tk.LEFT, padx=5)

        clear_btn = tk.Button(self.points_frame, text="清除坐标", command=self.clear_coordinates)
        clear_btn.pack(side=tk.LEFT, padx=5)

        # 存储选择的坐标点
        self.points = []

    def open_image(self):
        # 打开文件对话框选择图片
        file_path = filedialog.askopenfilename(
            title="选择图片",
            filetypes=[("图片文件", "*.png;*.jpg;*.jpeg;*.bmp;*.gif")]
        )

        if file_path:
            self.image_path = file_path
            self.load_image()
            self.status_bar.config(text=f"已加载图片: {os.path.basename(file_path)}")
            self.points = []
            self.points_listbox.delete(0, tk.END)

    def load_image(self):
        if not self.image_path:
            return

        # 打开并显示图片
        try:
            self.original_img = Image.open(self.image_path)
            self.scale_factor = 1.0
            self.display_image()
        except Exception as e:
            messagebox.showerror("错误", f"无法加载图片: {str(e)}")

    def display_image(self):
        if not self.original_img:
            return

        # 缩放图片
        width, height = self.original_img.size
        new_width = int(width * self.scale_factor)
        new_height = int(height * self.scale_factor)

        img = self.original_img.resize((new_width, new_height), Image.LANCZOS)
        self.photo_img = ImageTk.PhotoImage(img)

        # 清除画布并显示图片
        self.canvas.delete("all")
        self.image_item = self.canvas.create_image(0, 0, anchor=tk.NW, image=self.photo_img)

        # 绘制已选的坐标点
        for x, y in self.points:
            scaled_x = x * self.scale_factor
            scaled_y = y * self.scale_factor
            self.draw_point(scaled_x, scaled_y)

        # 更新画布滚动区域
        self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))

        # 重置视图
        self.canvas.xview_moveto(0)
        self.canvas.yview_moveto(0)

    def draw_point(self, x, y):
        # 在画布上绘制一个标记点和坐标文本
        radius = 5
        self.canvas.create_oval(x - radius, y - radius, x + radius, y + radius, fill="red")
        self.canvas.create_text(x + 15, y - 15, text=f"{int(x / self.scale_factor)},{int(y / self.scale_factor)}",
                                fill="red", font=("SimHei", 10))

    def on_mouse_move(self, event):
        # 鼠标移动时更新坐标显示
        if self.photo_img:
            # 获取鼠标在画布上的坐标
            canvas_x = self.canvas.canvasx(event.x)
            canvas_y = self.canvas.canvasy(event.y)

            # 获取鼠标在原图中的坐标
            x = int(canvas_x / self.scale_factor)
            y = int(canvas_y / self.scale_factor)
            self.coord_label.config(text=f"坐标: {x},{y}")

    def on_click(self, event):
        # 左键点击时记录坐标点
        if self.photo_img:
            # 获取鼠标在画布上的坐标
            canvas_x = self.canvas.canvasx(event.x)
            canvas_y = self.canvas.canvasy(event.y)

            # 获取鼠标在原图中的坐标
            x = int(canvas_x / self.scale_factor)
            y = int(canvas_y / self.scale_factor)

            # 检查坐标是否在图片范围内
            width, height = self.original_img.size
            if 0 <= x < width and 0 <= y < height:
                # 记录坐标点
                self.points.append((x, y))

                # 在画布上绘制点
                self.draw_point(canvas_x, canvas_y)

                # 更新坐标点列表
                self.points_listbox.insert(tk.END, f"{x},{y}")
                self.points_listbox.see(tk.END)

                # 自动复制坐标
                if self.auto_copy_var.get():
                    self.copy_last_coordinate()

    def on_mouse_wheel(self, event):
        # 鼠标滚轮缩放
        if not self.photo_img:
            return

        # 获取鼠标在画布上的位置
        x = self.canvas.canvasx(event.x)
        y = self.canvas.canvasy(event.y)

        # 计算缩放因子(Windows和Linux的event.delta不同)
        if event.num == 5 or event.delta < 0:  # 向下滚动 = 缩小
            self.scale_factor /= 1.2
        else:  # 向上滚动 = 放大
            self.scale_factor *= 1.2

        # 限制缩放范围
        self.scale_factor = max(0.1, min(self.scale_factor, 10.0))

        # 重新显示图片
        self.display_image()

        # 保持鼠标位置不变
        self.canvas.xview_moveto(x / (self.original_img.width * self.scale_factor))
        self.canvas.yview_moveto(y / (self.original_img.height * self.scale_factor))

    def copy_last_coordinate(self):
        # 复制最后一个坐标点到剪贴板
        if self.points:
            x, y = self.points[-1]
            coord_text = f"{x},{y}"
            self.root.clipboard_clear()
            self.root.clipboard_append(coord_text)
            self.status_bar.config(text=f"坐标 {coord_text} 已复制到剪贴板")

    def zoom_in(self):
        # 放大图片
        if self.original_img:
            self.scale_factor *= 1.2
            self.display_image()

    def zoom_out(self):
        # 缩小图片
        if self.original_img:
            self.scale_factor /= 1.2
            self.display_image()

    def reset_view(self):
        # 重置视图
        if self.original_img:
            self.scale_factor = 1.0
            self.display_image()

    def copy_coordinates(self):
        # 复制所有坐标点到剪贴板
        if self.points:
            coords_text = "\n".join([f"{x},{y}" for x, y in self.points])
            self.root.clipboard_clear()
            self.root.clipboard_append(coords_text)
            self.status_bar.config(text="坐标已复制到剪贴板")
        else:
            messagebox.showinfo("提示", "没有选择任何坐标点")

    def clear_coordinates(self):
        # 清除所有坐标点
        self.points = []
        self.points_listbox.delete(0, tk.END)
        self.display_image()
        self.status_bar.config(text="坐标点已清除")


if __name__ == "__main__":
    root = tk.Tk()
    app = ImageCoordinateTool(root)
    root.mainloop()

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
helian147 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

cqfyaaa 发表于 2025-5-31 17:45
成品地址一键传送:
https://wwje.lanzouu.com/ikqDO2xni6tc
密码:djyt
洹水清风 发表于 2025-5-31 16:06
MuLinShang 发表于 2025-5-31 18:28
cqfyaaa 发表于 2025-5-31 17:45
成品地址一键传送:
https://wwje.lanzouu.com/ikqDO2xni6tc
密码:djyt

以上win7版本不支持
W98 发表于 2025-5-31 22:25
cqfyaaa 发表于 2025-5-31 17:45
成品地址一键传送:
https://wwje.lanzouu.com/ikqDO2xni6tc
密码:djyt

大佬,我打包出来的包好大,依赖目录怎么选?
cqfyaaa 发表于 2025-6-1 14:22
W98 发表于 2025-5-31 22:25
大佬,我打包出来的包好大,依赖目录怎么选?

pip install pyinstaller
pip install pillow
pip install pywin32
sealist 发表于 2025-6-3 17:34
可以增加 在点击坐标点时显示对应像素的 RGB 值功能
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-20 22:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表