diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0259c84..e8141ec 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..4607527
--- /dev/null
+++ b/main.py
@@ -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("", 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("", self.myline)
+# elif name == "lineArrow":
+# self.drawPad.bind("", self.mylineArrow)
+# elif name == "rect":
+# self.drawPad.bind("", self.myRect)
+# elif name == "pen":
+# self.drawPad.bind("", self.myPen)
+# elif name == "erasor":
+# self.drawPad.bind("", 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()
\ No newline at end of file
diff --git a/pinPicture.py b/pinPicture.py
new file mode 100644
index 0000000..7b7edd0
--- /dev/null
+++ b/pinPicture.py
@@ -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("", self.close)
+ self.master.bind("", self.enter_canvas)
+ self.master.bind("", 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("", self.close)
+ self.canvas.bind("", self.stop_draw)
+ self.canvas.bind("", 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("", self.on_cut_start)
+ self.canvas.bind("", self.on_cut)
+ self.canvas.bind("", self.on_copy)
+ self.canvas.unbind("")
+ 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("", self.close)
+
+ def pin_mode_event(self):
+ self.canvas.bind("", self.on_drag_start)
+ self.canvas.bind("", self.on_drag)
+ self.canvas.bind("", 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("", self.pen)
+ self.penBtn.pack()
+ self.rectBtn.pack()
+ self.arrowBtn.pack()
+ self.lineBtn.pack()
+
+ def set_pen(self):
+ self.canvas.bind("", self.pen)
+
+ def set_rect(self):
+ self.canvas.bind("", self.rect)
+
+ def set_arrow(self):
+ self.canvas.bind("", self.arrow)
+
+ def set_line(self):
+ self.canvas.bind("", 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)
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..50a268b
Binary files /dev/null and b/requirements.txt differ