初始化

This commit is contained in:
awin-x 2025-01-15 20:08:02 +08:00
parent 1741825a55
commit e0d8d67e9b
4 changed files with 412 additions and 0 deletions

View File

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (ScreenCut)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (ScreenCut)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (ScreenCut)" project-jdk-type="Python SDK" />
</project> </project>

126
main.py Normal file
View File

@ -0,0 +1,126 @@
import pinPicture
from PIL import Image
import tkinter as tk
import pyautogui
import keyboard
def capture_screen():
screenshot = pyautogui.screenshot()
root = tk.Tk()
image = screenshot.convert('RGBA')
pin = pinPicture.PinPicture(image, root)
root.mainloop()
# 监听特定快捷键这里假设是Ctrl+Alt+S
keyboard.add_hotkey('F7', capture_screen)
# 保持程序运行,持续监听快捷键
keyboard.wait()
#
# from tkinter import Tk, Frame, Canvas, Button
# from tkinter.colorchooser import askcolor
#
#
# class Application(Frame):
# def __init__(self, master=None):
# super().__init__(master)
# self.master = master
# self.pack()
# self.createWidget()
# self.x = 0
# self.y = 0
# self.lastDraw = 0 # 最后绘制的图形id
# self.startDrawFlag = False
# self.fgcolor = "red"
#
# def createWidget(self):
# # 创建绘图区
# self.drawPad = Canvas(root, width=900, height=500, bg="black")
# self.drawPad.pack()
#
# # 画图软件的各种按钮
# btn_pen = Button(self, text="画笔", name="pen")
# btn_pen.pack(side="left", padx="10")
# btn_rect = Button(self, text="矩形", name="rect")
# btn_rect.pack(side="left", padx="10")
# btn_clear = Button(self, text="清屏", name="clear")
# btn_clear.pack(side="left", padx="10")
# btn_erasor = Button(self, text="橡皮擦", name="erasor")
# btn_erasor.pack(side="left", padx="10")
# btn_line = Button(self, text="直线", name="line")
# btn_line.pack(side="left", padx="10")
# btn_lineArrow = Button(self, text="箭头直线", name="lineArrow")
# btn_lineArrow.pack(side="left", padx="10")
# btn_color = Button(self, text="颜色", name="color")
# btn_color.pack(side="left", padx="10")
#
# # 为所有button绑定事件
# btn_pen.bind_class("Button", "<1>", self.eventManage)
# self.drawPad.bind("<ButtonRelease-1>", self.stopDraw)
#
# def stopDraw(self, event):
# self.startDrawFlag = False
# self.lastDraw = 0
#
# def startDraw(self, event):
# self.drawPad.delete(self.lastDraw)
# if not self.startDrawFlag:
# self.startDrawFlag = True
# self.x = event.x
# self.y = event.y
#
# def eventManage(self, event):
# name = event.widget.winfo_name()
# print(name)
# if name == "line":
# self.drawPad.bind("<B1-Motion>", self.myline)
# elif name == "lineArrow":
# self.drawPad.bind("<B1-Motion>", self.mylineArrow)
# elif name == "rect":
# self.drawPad.bind("<B1-Motion>", self.myRect)
# elif name == "pen":
# self.drawPad.bind("<B1-Motion>", self.myPen)
# elif name == "erasor":
# self.drawPad.bind("<B1-Motion>", self.myErasor)
# elif name == "clear":
# self.drawPad.delete("all")
# elif name == "color":
# c = askcolor(color=self.fgcolor, title="选择画笔颜色")
# self.fgcolor = c[1]
#
# def myline(self, event):
# self.startDraw(event)
# self.lastDraw = self.drawPad.create_line(self.x, self.y, event.x, event.y, fill=self.fgcolor)
#
# def mylineArrow(self, event):
# self.startDraw(event)
# self.lastDraw = self.drawPad.create_line(self.x, self.y, event.x, event.y, arrow=LAST, fill=self.fgcolor)
#
# def myRect(self, event):
# self.startDraw(event)
# self.lastDraw = self.drawPad.create_rectangle(self.x, self.y, event.x, event.y, outline=self.fgcolor)
#
# def myPen(self, event):
# self.startDraw(event)
# self.drawPad.create_line(self.x, self.y, event.x, event.y, fill=self.fgcolor)
# self.x = event.x
# self.y = event.y
#
# def myErasor(self, event):
# self.startDraw(event)
# self.drawPad.create_rectangle(event.x - 3, event.y - 3, event.x + 3, event.y + 3, fill="black")
# self.x = event.x
# self.y = event.y
#
#
# if __name__ == '__main__':
# root = Tk()
# root.geometry("900x500+200+200")
# root.title("画图软件")
# app = Application(master=root)
# root.mainloop()

283
pinPicture.py Normal file
View File

@ -0,0 +1,283 @@
import io
import math
import tkinter as tk
import win32clipboard
from PIL import Image, ImageTk, ImageChops, ImageDraw, ImageGrab
import threading
class PinPicture(tk.Frame):
def __init__(self, image, master=None):
super().__init__(master)
self.lineBtn = None
self.arrowBtn = None
self.rectBtn = None
self.penBtn = None
self.drawModeBtn = None
self.scale_factor = 1.0
self.photo = None
self.canvas = None
self.master = master
self.pad = Image.new('RGBA', image.size)
self.drawPad = ImageDraw.Draw(self.pad)
self.pack()
self.x = 0
self.y = 0
self.penX = 0
self.penY = 0
self.penX1 = 0
self.penY1 = 0
self.cutX = 0
self.cutY = 0
self.lastDraw = 0
self.drawing = False
self.drawMode = False
self.color = "red"
self.image = image
if image.mode != "RGBA":
image = image.convert("RGBA")
self.create_window()
self.penWidth = 3
self.arrowSize = 10
# 创建窗口
def create_window(self):
self.master.overrideredirect(True)
self.master.attributes('-transparentcolor', 'white')
self.master.config(bg='white')
self.master.attributes('-topmost', True)
self.canvas = tk.Canvas(self.master, height=self.image.height, width=self.image.width)
self.penBtn = tk.Button(text='', command=self.set_pen)
self.rectBtn = tk.Button(text='矩形', command=self.set_rect)
self.arrowBtn = tk.Button(text='箭头', command=self.set_arrow)
self.lineBtn = tk.Button(text='直线', command=self.set_line)
self.master.bind("<Escape>", self.close)
self.master.bind("<Enter>", self.enter_canvas)
self.master.bind("<Leave>", self.leave)
self.photo = ImageTk.PhotoImage(Image.alpha_composite(self.image, self.pad))
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.photo)
self.canvas.pack(fill=tk.BOTH, expand=True, side=tk.LEFT)
self.canvas.bind("<ButtonPress-3>", self.close)
self.canvas.bind("<ButtonRelease-1>", self.stop_draw)
self.canvas.bind("<Return>", self.on_save)
self.cut_mode_event()
def on_save(self, event):
output = io.BytesIO()
self.image.convert("RGB").save(output, "BMP")
data = output.getvalue()[14:] # BMP 文件头前14字节
output.close()
win32clipboard.OpenClipboard()
try:
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
finally:
win32clipboard.CloseClipboard()
def cut_mode_event(self):
self.canvas.bind("<ButtonPress-1>", self.on_cut_start)
self.canvas.bind("<B1-Motion>", self.on_cut)
self.canvas.bind("<ButtonPress-3>", self.on_copy)
self.canvas.unbind("<MouseWheel>")
self.pad = Image.new('RGBA', self.image.size, color=(0, 0, 0, 100))
self.drawPad = ImageDraw.Draw(self.pad)
def on_copy(self, event):
self.x = self.penX
self.y = self.penY
self.image = self.image.crop((self.penX, self.penY, self.cutX, self.cutY))
self.pad = Image.new('RGBA', self.image.size)
self.drawPad = ImageDraw.Draw(self.pad)
self.update_canvas()
self.master.geometry(f"+{self.x}+{self.y}")
self.pin_mode_event()
self.canvas.bind("<ButtonPress-3>", self.close)
def pin_mode_event(self):
self.canvas.bind("<ButtonPress-1>", self.on_drag_start)
self.canvas.bind("<B1-Motion>", self.on_drag)
self.canvas.bind("<MouseWheel>", self.on_mouse_wheel)
# 鼠标进入
def enter_canvas(self, event):
self.canvas.focus_set()
if self.drawModeBtn is None and not self.drawMode:
self.drawModeBtn = tk.Button(text="编辑", command=self.draw_mode_event)
self.drawModeBtn.pack(side=tk.TOP, expand=True)
elif not self.drawMode:
self.drawModeBtn.pack(side=tk.TOP, expand=True)
# 鼠标离开
def leave(self, event):
if self.drawModeBtn is not None and not self.drawMode:
self.drawModeBtn.pack_forget()
# 进入编辑模式
def draw_mode_event(self):
self.drawMode = True
self.drawModeBtn.pack_forget()
self.canvas.bind("<B1-Motion>", self.pen)
self.penBtn.pack()
self.rectBtn.pack()
self.arrowBtn.pack()
self.lineBtn.pack()
def set_pen(self):
self.canvas.bind("<B1-Motion>", self.pen)
def set_rect(self):
self.canvas.bind("<B1-Motion>", self.rect)
def set_arrow(self):
self.canvas.bind("<B1-Motion>", self.arrow)
def set_line(self):
self.canvas.bind("<B1-Motion>", self.line)
# 拖动图片设置窗口坐标
def on_drag(self, event):
delta_x = event.x - self.x
delta_y = event.y - self.y
new_x = self.master.winfo_x() + delta_x
new_y = self.master.winfo_y() + delta_y
self.master.geometry(f"+{new_x}+{new_y}")
def on_cut(self, event):
self.start_draw(event)
self.pad = Image.new('RGBA', self.image.size, color=(0, 0, 0, 100))
self.drawPad = ImageDraw.Draw(self.pad)
self.drawPad.rectangle((self.penX, self.penY, event.x, event.y), fill=(0,0,0,0), outline="purple")
self.update_canvas_cut()
self.cutX = event.x
self.cutY = event.y
# 记录开始拖动的坐标
def on_drag_start(self, event):
self.x = event.x
self.y = event.y
def on_cut_start(self, event):
self.pad = Image.new('RGBA', self.image.size, color=(0, 0, 0, 100))
self.drawPad = ImageDraw.Draw(self.pad)
self.penX = event.x
self.penY = event.y
# 关闭窗口
def close(self, event):
self.master.destroy()
# 滚轮调整大小
def on_mouse_wheel(self, event):
if self.drawMode:
if event.delta > 0:
self.penWidth += 1
self.arrowSize += 1
else:
self.penWidth -= 1
self.arrowSize -= 1
else:
if event.delta > 0:
self.scale_factor *= 1.1
else:
self.scale_factor /= 1.1
self.update_canvas()
def update_canvas(self):
new_width = int(self.image.width * self.scale_factor)
new_height = int(self.image.height * self.scale_factor)
image = Image.alpha_composite(self.image, self.pad)
image = image.resize((new_width, new_height))
self.photo = ImageTk.PhotoImage(image)
self.canvas.config(width=new_width, height=new_height)
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.photo)
def update_canvas_cut(self):
new_width = int(self.image.width * self.scale_factor)
new_height = int(self.image.height * self.scale_factor)
image1 = Image.alpha_composite(self.image, self.pad)
image1 = image1.resize((new_width, new_height))
self.photo = ImageTk.PhotoImage(image1)
self.canvas.config(width=new_width, height=new_height)
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.photo)
def start_draw(self, event):
if not self.drawing:
self.drawing = True
self.penX = event.x
self.penY = event.y
self.penY1 = event.y
self.penX1 = event.x
def pen(self, event):
self.start_draw(event)
self.drawPad.line(self.point_convert(self.penX, self.penY, event.x, event.y), self.color, width=self.penWidth)
self.drawPad.line(self.point_convert(self.penX1, self.penY1, event.x, event.y), self.color, width=self.penWidth)
self.penX1 = self.penX
self.penY1 = self.penY
self.penX = event.x
self.penY = event.y
self.update_canvas()
def line(self, event):
self.start_draw(event)
self.pad = Image.new('RGBA', self.image.size)
self.drawPad = ImageDraw.Draw(self.pad)
self.drawPad.line(self.point_convert(self.penX, self.penY, event.x, event.y), self.color, width=self.penWidth)
self.update_canvas()
def rect(self, event):
self.start_draw(event)
self.pad = Image.new('RGBA', self.image.size)
self.drawPad = ImageDraw.Draw(self.pad)
self.drawPad.line(self.point_convert(self.penX, self.penY, self.penX, event.y), self.color, width=self.penWidth)
self.drawPad.line(self.point_convert(self.penX, self.penY, event.x, self.penY), self.color, width=self.penWidth)
self.drawPad.line(self.point_convert(event.x, self.penY, event.x, event.y), self.color, width=self.penWidth)
self.drawPad.line(self.point_convert(self.penX, event.y, event.x, event.y), self.color, width=self.penWidth)
self.update_canvas()
def arrow(self, event):
self.start_draw(event)
self.pad = Image.new('RGBA', self.image.size)
self.drawPad = ImageDraw.Draw(self.pad)
pos = self.point_convert(self.penX, self.penY, event.x, event.y)
self.drawPad.line(pos, self.color, width=self.penWidth)
x1 = pos[0]
y1 = pos[1]
x2 = pos[2]
y2 = pos[3]
l = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
cosa = (x2 - x1) / l
sina = (y2 - y1) / l
k = sina / cosa
d = self.arrowSize * (sina + cosa)
if (sina < cosa):
xa = x2 - d
ya = y2 + math.sqrt(2 * self.arrowSize * self.arrowSize - d * d)
xb = x2 - math.sqrt(2 * self.arrowSize * self.arrowSize - d * d)
yb = y2 - d
else:
xa = x2 - d
ya = y2 - math.sqrt(2 * self.arrowSize * self.arrowSize - d * d)
xb = x2 + math.sqrt(2 * self.arrowSize * self.arrowSize - d * d)
yb = y2 - d
self.drawPad.polygon(
((xa, ya), (xb, yb), (pos[2], pos[3])),
fill=self.color, outline=(0, 0, 0, 0))
self.update_canvas()
def point_convert(self, x, y, x1, y1):
real_x = int(x / self.scale_factor)
real_y = int(y / self.scale_factor)
real_x1 = int(x1 / self.scale_factor)
real_y1 = int(y1 / self.scale_factor)
return real_x, real_y, real_x1, real_y1
def stop_draw(self, event):
self.drawing = False
if self.drawMode:
self.image = Image.alpha_composite(self.image, self.pad)
self.pad = Image.new('RGBA', self.image.size)
self.drawPad = ImageDraw.Draw(self.pad)

BIN
requirements.txt Normal file

Binary file not shown.