当前位置: 首页 > news >正文

动易与php环境架设网站成都新站软件快速排名

动易与php环境架设网站,成都新站软件快速排名,网上注册公司流程和方法,傻瓜式网页制作网站一、兼容局限性 这是用Python做的截图工具,不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境; 如果要提升其跨平台性的话,需要考虑替换cty…

一、兼容局限性

这是用Python做的截图工具,不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境;

如果要提升其跨平台性的话,需要考虑替换ctypes的一些专属于Windows的API以及设置不同的.cur访问方式

二、轻量化

该模块只使用了PIL这一个第三方库,和别的使用pygame\pyautogui等模块不同,该工具着重强调轻量化,无关或没必要使用的库尽可能不使用。

目前截图功能已经高度接近微信截图,不过没有编辑功能(建议保存后再编辑);里面包含了一些必备的快捷功能,不过还没有绑定快捷键;有需要者自行为代码中加入功能。

三、基础功能演示

功能演示

四、功能阐述

①基本的截图后等待,可继续移动边框,拖动调整上下左右对角位置(类似微信)

②打开图片文件,可以直接显示在面板上;

③复制图片文件到剪切板上;

④保存当前视图上的图片。

⑤对截取过的图片进行翻页,快速查看不同截图;

⑥删除视图中的图片,不影响磁盘文件,只是删除内存中的图片引用;

⑦通过调节窗口可动态调整图片在视图中的大小(不改变根引用图片);

⑧窗口置顶,即无论怎么打开其他窗口,该窗口都始终置于顶部不会被遮挡,方便我们对截图后的图片放置到一侧,参照图片进行操作

五、完整代码

代码如下,单文件,请自行安装PIL模块,确保在Windows环境上运行。

import os
import ctypes
import subprocess as sp
import tkinter as tk
from threading import Thread
from tkinter import messagebox, filedialog
from PIL import Image, ImageGrab, ImageTk, UnidentifiedImageErrorScaleFactor = ctypes.windll.shcore.GetScaleFactorForDevice(0)
ctypes.windll.shcore.SetProcessDpiAwareness(1)
TEMP_FILE_PATH = os.path.join(os.getenv("TEMP"), "tempScreenshot")
os.makedirs(TEMP_FILE_PATH, exist_ok=True)class FlatButton(tk.Label):def __init__(self, parent, command=None, enter_fg="#000000", click_color="#25C253", *args, **kwargs):super().__init__(parent, *args, **kwargs)self.__fg = fg = kwargs.get("fg", "#3B3B3B")self.__enter_fg = enter_fgself.__click_fg = click_colorself.command = commandself.config(cursor="hand2", fg=fg)self.enable()if fg == enter_fg:raise ValueError("enter_fg must be different from fg")def enable(self):self.bind("<Enter>", lambda _: self.config(fg=self.__enter_fg))self.bind("<Leave>", lambda _: self.config(fg=self.__fg))self.bind("<Button-1>", lambda _: self.config(fg=self.__click_fg))self.bind("<ButtonRelease-1>", self.__command)def disable(self):for event in ("<Enter>", "<Leave>", "<Button-1>", "<ButtonRelease-1>"):self.unbind(event)def __command(self, event):try:if self.cget("fg") in (self.__enter_fg, self.__click_fg):self.command(event)self.config(fg=self.__fg)except tk.TclError:passexcept TypeError:self.config(fg=self.__fg)class AdjustableRect(object):"""The judgement seq is so important that you must care about:(right, bottom), (left, top), (right, top), (left, bottom),(center_x, top), (center_x, bottom), (left, center_y, ), (right, center_y)"""ANCHOR_SIZE = 3ANCHOR_HOVER_DISTANCE = 20CURSOR_FILES_NAME = ["aero_nwse_l.cur", "aero_nesw_l.cur", "aero_ns_l.cur", "aero_ew_l.cur"]CURSOR_FILES = [f"@C:/Windows/Cursors/{cursor_file}" for cursor_file in CURSOR_FILES_NAME]CURSORS = [CURSOR_FILES[0], CURSOR_FILES[0], CURSOR_FILES[1], CURSOR_FILES[1],CURSOR_FILES[2], CURSOR_FILES[2], CURSOR_FILES[3], CURSOR_FILES[3],"fleur", "arrow"]def __init__(self, parent, screenshot):self.parent: tk.Canvas = parentself.screenshot: ScreenshotUtils = screenshotself.__rect: int = 0self.__anchors: list[int] = []self.anchor_id: int = 0def rect_coords(self) -> tuple[int, int, int, int]:return self.parent.coords(self.__rect)def anchor_coords(self) -> tuple[int, int, int, int]:left, top, right, bottom = self.rect_coords()horizontal_middle = (left + right) // 2vertical_middle = (top + bottom) // 2return ((left, top), (horizontal_middle, top), (right, top), (right, vertical_middle),(right, bottom), (horizontal_middle, bottom), (left, bottom), (left, vertical_middle))def rect_width_height(self) -> tuple[int, int]:left, top, right, bottom = self.rect_coords()return int(right - left), int(bottom - top)def get_anchor(self, event) -> int:cls = self.__class__left, top, right, bottom = self.rect_coords()center_x, center_y = (left + right) // 2, (top + bottom) // 2def near(actual, target):return abs(actual - target) < cls.ANCHOR_HOVER_DISTANCE# 务必注意这个判断顺序,这与后面rect_adjust密切相关judgement_pos = ((right, bottom), (left, top), (right, top), (left, bottom),(center_x, top), (center_x, bottom), (left, center_y, ), (right, center_y))for index, pos in enumerate(judgement_pos):if near(event.x, pos[0]) and near(event.y, pos[1]):return indexif left < event.x < right and top < event.y < bottom:return 8return -1def create_anchors(self):cls = self.__class__for coord in self.anchor_coords():anchor = self.parent.create_rectangle(coord[0]-cls.ANCHOR_SIZE, coord[1]-cls.ANCHOR_SIZE,coord[0]+cls.ANCHOR_SIZE, coord[1]+cls.ANCHOR_SIZE,fill="#1AAE1A", outline="#1AAE1A")self.__anchors.append(anchor)def create_rect(self) -> None:self.__rect= self.parent.create_rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, outline='#1AAE1A', width=2)self.create_anchors()def move_anchors(self):cls = self.__class__for anchor, coord in zip(self.__anchors, self.anchor_coords()):self.parent.coords(anchor, coord[0]-cls.ANCHOR_SIZE, coord[1]-2, coord[0]+cls.ANCHOR_SIZE, coord[1]+cls.ANCHOR_SIZE)def on_press(self, event):self.screenshot.start_x = event.xself.screenshot.start_y = event.ydef on_release(self, _):self.screenshot.start_x, self.screenshot.start_y,\self.screenshot.end_x, self.screenshot.end_y = self.rect_coords()def on_hover(self, event):self.anchor_id = self.get_anchor(event)cursor = self.CURSORS[self.anchor_id]self.parent.config(cursor=cursor)def move_rect(self, event):offset_x = event.x - self.screenshot.move_start_xoffset_y = event.y - self.screenshot.move_start_yif self.screenshot.start_x + offset_x > 0 and self.screenshot.end_x + offset_x < SCREEN_WIDTH:self.screenshot.start_x += offset_xself.screenshot.end_x += offset_xif  self.screenshot.start_y + offset_y > 0 and self.screenshot.end_y + offset_y < SCREEN_HEIGHT:self.screenshot.start_y += offset_yself.screenshot.end_y += offset_yself.screenshot.move_start_x = event.xself.screenshot.move_start_y = event.yself.parent.coords(self.__rect, self.screenshot.start_x, self.screenshot.start_y, self.screenshot.end_x, self.screenshot.end_y)self.move_anchors()def rect_adjust(self, event):if self.anchor_id == 8:return self.move_rect(event)if self.anchor_id == 0:self.screenshot.end_x, self.screenshot.end_y = event.x, event.yelif self.anchor_id == 1:self.screenshot.start_x, self.screenshot.start_y = event.x, event.yelif self.anchor_id == 2:self.screenshot.end_x, self.screenshot.start_y = event.x, event.yelif self.anchor_id == 3:self.screenshot.start_x, self.screenshot.end_y = event.x, event.yelif self.anchor_id == 4:self.screenshot.start_y = event.yelif self.anchor_id == 5:self.screenshot.end_y = event.yelif self.anchor_id == 6:self.screenshot.start_x = event.xelif self.anchor_id == 7:self.screenshot.end_x = event.xelse:returnself.parent.coords(self.__rect, self.screenshot.start_x, self.screenshot.start_y, self.screenshot.end_x, self.screenshot.end_y)self.move_anchors()class ScreenshotUtils(object):"""截图的关键是坐标;这个类管理着图片的引用和截图坐标;"""def TkS(value) -> int:return int(ScaleFactor/100*value)ZOOM: int = 4ZOOM_WIDTH: float = TkS(28.75)ZOOM_SCREEN_SIZE: int = int(ZOOM_WIDTH*ZOOM)MAGNIFIER_OFFSET: int = 36WIDTH_HEIGHT_OFFSET = 40POS_TAG_GAP = 10RGB_TAG_GAP = 47MAGNIFIER_ADJUST = 70AJUST_BAR_WIDTH: int = TkS(100)def __init__(self):self.start_x = self.start_y = self.end_x = self.end_y = 0self.move_start_x = self.move_start_y = self.move_end_x = self.move_end_y = 0self.page_index: int = 0self.current_image: Image.Image = Noneself.pixel_reader = Noneself.final_images: list[Image.Image] = list()# 这种是只移动但不改变大小和内容的控件,只需移动无需重绘self.screenshot_move_widget = list()# 这种是移动和改变大小的控件,需要实时重绘self.screenshot_redraw_widget = list()@staticmethoddef TkS(value) -> int:return int(ScaleFactor/100*value)@classmethoddef move_widget_coords(cls, x, y) -> list[tuple[int, int, int, int]]:# 按照主框架,水平线,垂直线的顺序返回坐标main_frame_coord  = (x, y, x+cls.ZOOM_SCREEN_SIZE, y+cls.ZOOM_SCREEN_SIZE)horrontal_line_coord = (x, y+cls.ZOOM_SCREEN_SIZE // 2, x+cls.ZOOM_SCREEN_SIZE, y+cls.ZOOM_SCREEN_SIZE // 2)vertical_line_coord = (x+cls.ZOOM_SCREEN_SIZE // 2, y, x+cls.ZOOM_SCREEN_SIZE // 2, y+cls.ZOOM_SCREEN_SIZE)return [main_frame_coord, horrontal_line_coord, vertical_line_coord]def redraw_widget_coords(self, x, y) -> list[tuple]:# 按照"放大镜图像"、"长 × 宽"、"POS标签"、"RGB标签"的顺序返回坐标offset = self.__class__.MAGNIFIER_OFFSETzoom_size = self.__class__.ZOOM_SCREEN_SIZEif x + offset + zoom_size < SCREEN_WIDTH:x_offset = x + offsetelse:x_offset = x - offset - zoom_sizeif y + offset + zoom_size + self.__class__.MAGNIFIER_ADJUST < SCREEN_HEIGHT:y_offset = y + offsetelse:y_offset = y - offset - zoom_size - self.__class__.MAGNIFIER_ADJUSTwidth_height_y = max(min(self.start_y, self.end_y) - self.__class__.WIDTH_HEIGHT_OFFSET, 0)width_height_info = (max(min(self.start_x, self.end_x), 0), width_height_y)magnifier_coord = (x_offset, y_offset)pos_info = (x_offset, y_offset + zoom_size + self.__class__.POS_TAG_GAP)rgb_info = (x_offset, y_offset + zoom_size + self.__class__.RGB_TAG_GAP)return [magnifier_coord, width_height_info, pos_info, rgb_info]class MainUI(tk.Tk):def __init__(self):super().__init__()self.screenshot = ScreenshotUtils()self.set_window()self.menu_bar: tk.Frame = self.set_menubar()self.cut_btn: FlatButton = self.set_cut_btn()self.load_image_btn: FlatButton = self.set_load_image_btn()self.copy_btn: FlatButton = self.set_copy_btn()self.save_btn: FlatButton = self.set_save_btn()self.turn_left_btn: FlatButton = self.set_turn_left_btn()self.turn_right_btn: FlatButton = self.set_turn_right_btn()self.delete_btn: FlatButton = self.set_delete_btn()self.show_image_canvas: tk.Canvas = self.set_show_image_canvas()self.capture_win: tk.Toplevel = Noneself.full_screenshot_canvas: tk.Canvas = Noneself.adjust_rect: AdjustableRect = Noneself.adjust_bar: tk.Frame = Nonedef set_window(self):self.title("截图工具")width, height = self.screenshot.TkS(255), self.screenshot.TkS(30)self.minsize(width=width, height=height)  # 这里可以根据需要调整最小宽高self.attributes("-topmost", True)self.geometry(f"{width}x{height}")def set_menubar(self) -> tk.Frame:menubar = tk.Frame(self, bg="#FFFFFF", height=ScreenshotUtils.TkS(30))menubar.pack(fill=tk.X)menubar.pack_propagate(False)  # 阻止内部组件改变框架大小return menubardef set_cut_btn(self) -> FlatButton:btn_cut = FlatButton(self.menu_bar, text="✂", bg="#FFFFFF", font=("Segoe UI Emoji", 18),)btn_cut.pack(side=tk.LEFT, ipadx=0.1)return btn_cutdef set_load_image_btn(self) -> FlatButton:btn_load = FlatButton(self.menu_bar, text="📄", bg="#FFFFFF",font=("Segoe UI Emoji", 18, "bold"))btn_load.pack(side=tk.LEFT, ipadx=0.1)return btn_loaddef set_copy_btn(self) -> FlatButton:btn_copy = FlatButton(self.menu_bar, text="⎘", bg="#FFFFFF", font=("Segoe UI Symbol", 26),)btn_copy.pack(side=tk.LEFT, ipadx=0.1)return btn_copydef set_save_btn(self) -> FlatButton:btn_save = FlatButton(self.menu_bar, text="💾", bg="#FFFFFF", font=("Segoe UI Emoji", 18),)btn_save.pack(side=tk.LEFT, ipadx=0.1)return btn_savedef set_turn_left_btn(self) -> FlatButton:turn_left_btn = FlatButton(self.menu_bar, text="\u25C0", bg="#FFFFFF", font=("Segoe UI Emoji", 18),)turn_left_btn.pack(side=tk.LEFT, ipadx=0.1)return turn_left_btndef set_turn_right_btn(self) -> FlatButton:turn_page_btn = FlatButton(self.menu_bar, text="\u25B6", bg="#FFFFFF", font=("Segoe UI Emoji", 18),)turn_page_btn.pack(side=tk.LEFT, ipadx=0.1)return turn_page_btndef set_delete_btn(self) -> FlatButton:delete_btn = FlatButton(self.menu_bar, text="🗑", bg="#FFFFFF", font=("Segoe UI Symbol", 26, "bold"),)delete_btn.pack(side=tk.LEFT, ipadx=0.1)return delete_btndef set_cancel_btn(self, parent) -> FlatButton:cancel_btn = FlatButton(parent, self.clear_capture_info, text="×", bg="#FFFFFF",enter_fg="#DB1A21",fg="#CC181F", font=("微软雅黑", 20))cancel_btn.pack(side=tk.RIGHT, padx=5)return cancel_btndef set_confirm_btn(self, parent) -> FlatButton:confirm_btn = FlatButton(parent, self.confirm_capture, fg="#23B34C", text="√",enter_fg="#27C956", bg="#FFFFFF", font=("微软雅黑", 20))confirm_btn.pack(side=tk.RIGHT, padx=10)return confirm_btndef set_show_image_canvas(self) -> tk.Canvas:canvas = tk.Canvas(self, bg="white")return canvasdef set_adjust_bar(self) -> tk.Frame:self.adjust_bar = tk.Frame(self.full_screenshot_canvas, bg="#FFFFFF", height=50)cancel_btn = self.set_cancel_btn(self.adjust_bar)confirm_btn = self.set_confirm_btn(self.adjust_bar)cancel_btn.pack(side=tk.RIGHT, padx=5)confirm_btn.pack(side=tk.RIGHT, padx=10)def set_magnifier_frame(self, event) -> None:initial_coord = (0, 0, 0, 0)main_frame_id = self.full_screenshot_canvas.create_rectangle(*initial_coord, outline='#1AAE1A', width=1)horrontal_line = self.full_screenshot_canvas.create_line(*initial_coord, fill="#1AAE1A", width=2)vertical_line = self.full_screenshot_canvas.create_line(*initial_coord, fill="#1AAE1A", width=2)self.screenshot.screenshot_move_widget = [main_frame_id, horrontal_line, vertical_line]event.x = event.x + event.widget.winfo_rootx()event.y = event.y + event.widget.winfo_rooty()def set_full_screenshot_canvas(self, parent) -> tk.Canvas:img = ImageGrab.grab()self.screenshot.current_image = imgself.screenshot.pixel_reader = img.convert("RGB")photo = ImageTk.PhotoImage(img)full_screenshot_canvas = tk.Canvas(parent, bg="white", highlightthickness=0)full_screenshot_canvas.create_image(0, 0, anchor=tk.NW, image=photo)full_screenshot_canvas.image = photofull_screenshot_canvas.pack(fill=tk.BOTH, expand=True)return full_screenshot_canvasdef config_pos_rgb_info(self, parent: tk.Canvas, pos: str, rgb: str, pos_coord: tuple[int, int], rgb_coord: tuple[int, int]) -> tuple[int]:style = {"anchor": tk.NW, "font": ("微软雅黑", 9), "fill": "#FFFFFF"}pos_info = parent.create_text(*pos_coord, text=pos, **style)rgb_info = parent.create_text(*rgb_coord, text=rgb, **style)pos_bg = parent.create_rectangle(*parent.bbox(pos_info), outline="#000000", fill="#000000")rgb_bg = parent.create_rectangle(*parent.bbox(rgb_info), outline="#000000", fill="#000000")parent.tag_raise(pos_info)parent.tag_raise(rgb_info)return pos_info, rgb_info, pos_bg, rgb_bgclass ScreenshotTool(MainUI):def __init__(self):super().__init__()self.add_command()def add_command(self):self.protocol("WM_DELETE_WINDOW", self.on_close)self.show_image_canvas.bind("<Configure>", self.auto_adjust_image_size)self.cut_btn.command = self.start_captureself.load_image_btn.command = self.load_imageself.copy_btn.command = self.copy_imageself.save_btn.command = self.save_imageself.turn_left_btn.command = self.turn_pageself.turn_right_btn.command = self.turn_pageself.delete_btn.command = self.delete_imagedef initialize_screenshot_coords(self):self.is_drag = Falseself.screenshot.start_x = self.screenshot.start_y = 0self.screenshot.end_x = SCREEN_WIDTHself.screenshot.end_y = SCREEN_HEIGHTdef start_capture(self, event):self.attributes('-alpha', 0)self.update()self.capture_win = tk.Toplevel()self.capture_win.geometry(f"{SCREEN_WIDTH}x{SCREEN_HEIGHT}+0+0")self.capture_win.overrideredirect(True)self.full_screenshot_canvas = self.set_full_screenshot_canvas(self.capture_win)self.adjust_rect = AdjustableRect(self.full_screenshot_canvas, self.screenshot)self.initialize_screenshot_coords()self.adjust_rect.create_rect()self.set_magnifier_frame(event)self.update_magnifier(event)self.set_adjust_bar()self.full_screenshot_canvas.bind("<Button-1>", self.on_press)self.full_screenshot_canvas.bind("<Motion>", self.update_magnifier)self.full_screenshot_canvas.bind("<ButtonRelease-1>", self.on_release)def on_press(self, event) -> None:self.adjust_rect.on_press(event)self.full_screenshot_canvas.unbind("<Motion>")self.full_screenshot_canvas.bind("<Motion>", self.on_drag)def on_drag(self, event) -> None:self.adjust_rect.rect_adjust(event)self.update_magnifier(event)def on_release(self, event, resize=True) -> None:self.unbind_all()self.adjust_rect.on_release(event)self.full_screenshot_canvas.bind("<Button-1>", self.enter_adjust_mode)self.full_screenshot_canvas.bind("<Motion>", self.adjust_rect.on_hover)self.adjust_bar.place(x=min(self.screenshot.end_x - 300, SCREEN_WIDTH - 300), width=300,y=max(min(self.screenshot.end_y + 10, SCREEN_HEIGHT - ScreenshotUtils.TkS(40)), 0),)if resize:self.screenshot.end_x, self.screenshot.end_y = event.x, event.yself.conceal_move_widget()self.update_width_height_info(event)def rect_adjust(self, event) -> None:self.adjust_rect.rect_adjust(event)if self.adjust_rect.anchor_id != 8 or self.adjust_rect.anchor_id == -1:self.update_magnifier(event)def unbind_all(self):events = ("<Button-1>", "<Motion>", "<ButtonRelease-1>")for event in events:self.full_screenshot_canvas.unbind(event)def clear_redraw_widget(self) -> None:for redraw_widget in self.screenshot.screenshot_redraw_widget:self.full_screenshot_canvas.delete(redraw_widget)self.screenshot.screenshot_redraw_widget.clear()def conceal_move_widget(self):for widget in self.screenshot.screenshot_move_widget:self.full_screenshot_canvas.tag_lower(widget)def update_width_height_info(self, event) -> None:self.clear_redraw_widget()w, h = self.adjust_rect.rect_width_height()coord = self.screenshot.redraw_widget_coords(event.x, event.y)[1]wh_info_widget = self.full_screenshot_canvas.create_text(*coord, anchor=tk.NW, fill="white", text=f"{w} × {h}")self.screenshot.screenshot_redraw_widget = [wh_info_widget]def update_magnifier(self, event, ) -> None:x, y = event.x, event.ysize = ScreenshotUtils.ZOOM_WIDTHimg = self.screenshot.current_image.crop((x - size//2, y - size//2, x + size//2, y + size//2))img = img.resize((ScreenshotUtils.ZOOM_SCREEN_SIZE, ScreenshotUtils.ZOOM_SCREEN_SIZE))photo = ImageTk.PhotoImage(img)self.full_screenshot_canvas.image2 = photow, h = self.adjust_rect.rect_width_height()self.clear_redraw_widget()redraw_widget_coords = self.screenshot.redraw_widget_coords(x, y)magnifier_coord, width_height_info, pos_coord, rgb_coord = redraw_widget_coordszoom_img = self.full_screenshot_canvas.create_image(*magnifier_coord, anchor=tk.NW, image=photo)wh_info_widget = self.full_screenshot_canvas.create_text(*width_height_info, anchor=tk.NW, fill="white", text=f"{w} × {h}")pos_rgb_info = self.config_pos_rgb_info(self.full_screenshot_canvas, f"POS: ({x}, {y})", f"RGB: {self.screenshot.pixel_reader.getpixel((x, y))}", pos_coord, rgb_coord)self.screenshot.screenshot_redraw_widget = [zoom_img, wh_info_widget, *pos_rgb_info]self.update_magnifier_frame(*self.full_screenshot_canvas.coords(zoom_img))def update_magnifier_frame(self, x, y) -> None:coords = self.screenshot.move_widget_coords(x, y)for widget, coord in zip(self.screenshot.screenshot_move_widget, coords):self.full_screenshot_canvas.coords(widget, *coord)self.full_screenshot_canvas.tag_raise(widget)def enter_adjust_mode(self, event) -> None:self.screenshot.move_start_x = event.xself.screenshot.move_start_y = event.yself.adjust_bar.place_forget()for widget in self.screenshot.screenshot_redraw_widget:self.full_screenshot_canvas.delete(widget)for widget in self.screenshot.screenshot_move_widget:self.full_screenshot_canvas.tag_lower(widget)self.full_screenshot_canvas.bind("<B1-Motion>", self.rect_adjust)self.full_screenshot_canvas.bind("<ButtonRelease-1>", lambda e: self.on_release(e, False))def clear_capture_info(self, _) -> None:self.capture_win.destroy()self.full_screenshot_canvas.destroy()self.attributes('-alpha', 1)self.screenshot.screenshot_move_widget.clear()def check_capture_screenshot(self) -> None:if self.screenshot.start_x == self.screenshot.end_x or \self.screenshot.start_y == self.screenshot.end_y:self.initialize_screenshot_coords()def confirm_capture(self, event) -> None:x1, y1, x2, y2 = self.adjust_rect.rect_coords()self.clear_capture_info(event)image = self.screenshot.current_image.crop((x1, y1, x2, y2))result = self.show_image(image)self.screenshot.final_images.append(result)self.screenshot.page_index = len(self.screenshot.final_images) - 1self.attributes('-topmost', 1)def show_image(self, image: Image.Image, window_resize=True) -> None:if window_resize:self.geometry(f"{image.width}x{image.height+self.menu_bar.winfo_height()}")photo = ImageTk.PhotoImage(image)self.show_image_canvas.delete("all")self.show_image_canvas.create_image(0, 0, anchor=tk.NW, image=photo)self.show_image_canvas.image = photoself.show_image_canvas.pack(fill=tk.BOTH, expand=True)return imagedef current_limiting(self, canvas_w, canvas_h) -> bool:if not self.screenshot.final_images:return Truetry:coords = self.show_image_canvas.bbox("all")img_view_w, img_view_h = coords[2], coords[3]except TypeError:return Trueif (img_view_w == canvas_w and img_view_h < canvas_h) or \(img_view_h == canvas_h and img_view_w < canvas_w):return Truereturn Falsedef auto_adjust_image_size(self, _) -> None:canvas_w = self.show_image_canvas.winfo_width()canvas_h = self.show_image_canvas.winfo_height()if self.current_limiting(canvas_w, canvas_h):returnimage = self.screenshot.final_images[self.screenshot.page_index]width_ratio = canvas_w / image.widthheight_ratio = canvas_h / image.heightratio = min(width_ratio, height_ratio)new_width = int(image.width * ratio)new_height = int(image.height * ratio)resized_image = image.resize((new_width, new_height), Image.LANCZOS)self.show_image(resized_image, False)def load_image(self, _) -> None:file_types = (("Image files", "*.jpg *.png *.jpeg"),)img_path = filedialog.askopenfilename(filetypes=file_types)if not img_path:returntry:image = Image.open(img_path)except UnidentifiedImageError:return messagebox.showerror("错误", "无法识别该图片文件!")self.show_image(image)self.screenshot.final_images.append(image)self.screenshot.page_index = len(self.screenshot.final_images) - 1def copy_image(self, _) -> None:def __copy_image():self.copy_btn.disable()self.copy_btn.config(fg="#25C253")image = self.screenshot.final_images[self.screenshot.page_index]temp_name = f"{int.from_bytes(os.urandom(4), byteorder='big')}.png"temp_file = os.path.join(TEMP_FILE_PATH, temp_name)image.save(temp_file)startupinfo = sp.STARTUPINFO()startupinfo.dwFlags |= sp.STARTF_USESHOWWINDOWargs = ['powershell', f'Get-Item {temp_file} | Set-Clipboard']process = sp.Popen(args=args, startupinfo=startupinfo)process.wait()self.title("截图工具")self.copy_btn.enable()self.copy_btn.config(fg="#3B3B3B")if len(self.screenshot.final_images) == 0:return messagebox.showerror("复制失败", "未检测到截取图像")self.title("复制成功!")Thread(target=__copy_image, daemon=True).start()def save_image(self, _) -> None:try:image = self.screenshot.final_images[self.screenshot.page_index]filename = filedialog.asksaveasfilename(defaultextension=".png",filetypes=[("PNG files", "*.png"), ("JPEG files", "*.jpg")],initialfile=f"{image.width}x{image.height}.png")if not filename:returnimage.save(filename)except IndexError:messagebox.showerror("保存失败", "未检测到截取图像")def turn_page(self, event) -> None:if len(self.screenshot.final_images) == 0:return messagebox.showinfo("提示", "暂无图片可切换!")if event.widget == self.turn_left_btn:if self.screenshot.page_index == 0:return messagebox.showinfo("提示", "已经是第一张图片!")self.screenshot.page_index -= 1else:if self.screenshot.page_index == len(self.screenshot.final_images) - 1:return messagebox.showinfo("提示", "已经是最后一张图片!")self.screenshot.page_index += 1self.show_image(self.screenshot.final_images[self.screenshot.page_index])def delete_image(self, _) -> None:if len(self.screenshot.final_images) == 0:return messagebox.showinfo("提示", "暂无图片可删除!")if not messagebox.askokcancel("提示", "确认删除当前图片?"):returnself.screenshot.final_images.pop(self.screenshot.page_index)if self.screenshot.page_index == len(self.screenshot.final_images):self.screenshot.page_index -= 1if len(self.screenshot.final_images) == 0:self.show_image_canvas.delete("all")self.geometry(f"{self.screenshot.TkS(255)}x{self.screenshot.TkS(30)}")else:self.show_image(self.screenshot.final_images[self.screenshot.page_index])def on_close(self):def delete_tmp_files():for file in os.scandir(TEMP_FILE_PATH):os.remove(file)self.destroy()Thread(target=delete_tmp_files).start()if __name__ == "__main__":app = ScreenshotTool()SCREEN_WIDTH = app.winfo_screenwidth()SCREEN_HEIGHT = app.winfo_screenheight()app.mainloop()

六、打包程序

如无Python环境,可以通过以下链接下载:
链接:https://pan.quark.cn/s/f87bf5f9e825
提取码:nMGP

http://www.tj-hxxt.cn/news/67194.html

相关文章:

  • 公司网站下二级站点如何做流量大的推广平台有哪些
  • dede网站seoseo搜索优化是什么意思
  • 南戴河区网站建设哪家好产品软文代写
  • 私人让做彩票网站吗网络营销师报考条件
  • 网龙沧州网站制作shopify seo
  • 济南网站建设泉诺宁波网站推广公司有哪些
  • 四川省建设厅职称查询网站公司怎么做网络营销
  • 微信公众号做特效的网站宣传推广
  • 在国外社交网站做产品推广营销软文800字范文
  • wordpress 一键建站营销型网站建设需要多少钱
  • 免费微信网站建设网络营销的好处
  • 贵州省建设执业资格教育促进会网站河北百度推广seo
  • 网站建设框架百度一下你就知道原版
  • 怎么做狼视听网站seo是什么技术
  • 鄂州人民政府网站seo管理工具
  • 怎么做pc端移动网站好看的网页设计作品
  • b站做简介的网站营销和运营的区别是什么
  • 企业网站维护建设ppt百度seo详解
  • 报名网站建设百度竞价的优势和劣势
  • 以前做的网站怎么才能登陆后台百度一下首页设为主页
  • 网站 设计 工具网络推广项目外包公司
  • jsp网站建设毕业设计建设网官方网站
  • 金耀网站建设网站制作怎样做企业推广
  • wordpress响应速度太慢长春seo顾问
  • 橙色可以做哪些网站如何创建微信小程序
  • 控制网站的大量访问网络推广有多少种方法
  • 企业网站建设排名网址app推广员好做吗
  • 日本药妆电子商务网站建设规划书网易搜索引擎入口
  • 做网站公司的排名网络营销实施方案
  • 微信扫一扫登录网站如何做永久免费的培训学校管理软件