1.使用方法:打开软件,选择图片,然后图片上选择两个点,输入想
要两个点之间的距离,单位mm,点计算结果宽度(这个结果是图片应
该的宽度),然后输出pdf即可。pdf是a4大小
2.也可以手动直接输入最终的图片宽度来打印
3.用了低版本Python编译,win7 32位应该可以运行了,没测试
4.更新了1.6版本, 加了个放大镜方便选择图片里的点
链接:https://pan.baidu.com/s/1wQ_w4U3JtX-HpZC3z_ELpA 提取码:5osy
界面就只有这能力了,都是问的ai,图片显示不能放大缩小,是把原图缩放了显示进去的,只能说能用
2_proc.jpg (65.57 KB, 下载次数: 0)
下载附件
2024-8-20 22:02 上传
1_proc.jpg (58.98 KB, 下载次数: 0)
下载附件
2024-8-20 22:02 上传
[Python] 纯文本查看 复制代码# 导入必要的库
import cv2
import numpy as np
from tkinter import Tk, Button, Label, Entry, filedialog, Canvas, messagebox
from PIL import Image, ImageTk
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
# 定义ImageSelector类
class ImageSelector:
def __init__(self, root):
# 初始化根窗口和类属性
self.root = root
self.root.title('图像选择器与PDF创建器')
self.original_image = None
self.photo_image = None
self.points = []
self.result = None
self.original_image_path = None
self.scale = 1.0 # 初始化缩放比例
self.first_point = None # 新增属性,保存第一个点的坐标
self.line1 = None # 新增属性,保存实时连接线的对象
self.zoom_canvas = None # 新增属性,保存用于显示放大图像的画板
# 创建垂直布局的框架
self.frame = Canvas(self.root, width=200, height=750)
self.frame.pack(side='right', fill='y')
# 在框架内创建按钮、标签等
self.load_image_button = self.create_button('加载图片', self.load_image)
self.canvas = self.create_canvas()
self.clear_button = self.create_button('清除标记点', self.clear_points)
self.entry_label = self.create_label('输入两点间距离(mm):')
self.entry = Entry(self.frame, width=20)
self.entry.pack(side='top', fill='x')
self.result_button = self.create_button('计算宽度', self.calculate_result)
self.result_label = Label(self.frame, text="计算出的图片宽度(mm): ", font=('Arial', 12))
self.result_label.pack(side='top', padx=10, pady=5)
self.create_pdf_button = self.create_button('创建PDF', self.create_pdf)
self.result_entry = Entry(self.frame, width=20)
self.result_entry.pack(side='top', fill='x')
self.result_entry.bind("", lambda event: app.update_result_from_input(app.result_entry.get()))
self.manual_update_button = self.create_button('手动输入图片宽度(mm)', lambda: app.update_result_from_input(app.result_entry.get()))
# 创建用于显示放大图像的小画板,并将其放置在框架的下方
self.zoom_canvas = Canvas(self.frame, width=200, height=200, bg='white') # 根据需要调整尺寸
self.zoom_canvas.pack(side='top')
# 创建按钮的方法
def create_button(self, text, command):
button = Button(self.frame, text=text, command=command)
button.pack(fill='x')
return button
# 创建画布的方法
def create_canvas(self):
# 创建主画板
canvas = Canvas(self.root, width=1000, height=750)
canvas.pack(side='left', fill='both', expand=True)
canvas.bind("[B]", self.on_canvas_click)
canvas.bind("", self.on_canvas_motion)
# 创建用于显示放大图像的画板
#self.zoom_canvas = Canvas(self.root, width=100, height=100, bg='white')
#self.zoom_canvas.pack(side='right', padx=10, pady=10)
return canvas
# 创建标签的方法
def create_label(self, text):
label = Label(self.frame, text=text)
label.pack(side='top', fill='x')
return label
# 加载图像的方法
def load_image(self):
file_path = filedialog.askopenfilename(
title = "选择图片",
filetypes = (("JPG files", "*.jpg"), ("PNG files", "*.png"), ("All files", "*.*"))
)
if file_path:
self.original_image = self.imread_with_chinese_chars(file_path)
if self.original_image is None:
messagebox.showerror("Error", "图片未找到,请检查路径。")
return
self.original_image_path = file_path
canvas_size = (self.canvas.winfo_width(), self.canvas.winfo_height())
self.photo_image, self.scale = self.resize_image(self.original_image, canvas_size)
self.canvas.create_image(0, 0, image=self.photo_image, anchor='nw')
self.canvas.image = self.photo_image
# 读取中文路径图片的方法
def imread_with_chinese_chars(self, file_path):
image = Image.open(file_path)
return cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
# 调整图像大小的方法,保持比例
def resize_image(self, image, canvas_size):
(h, w) = image.shape[:2]
(cw, ch) = canvas_size
scale = min(cw/w, ch/h)
new_size = (int(w * scale), int(h * scale))
new_image = cv2.resize(image, new_size, interpolation=cv2.INTER_AREA)
canvas_image = Image.fromarray(cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB))
return ImageTk.PhotoImage(canvas_image), scale
# 画布点击事件的回调方法
def on_canvas_click(self, event):
#self.update_zoom_canvas(event.x, event.y)
if self.first_point is None:
# 第一次点击,记录第一个点的位置
self.first_point = (event.x, event.y)
self.line1 = self.canvas.create_line(
self.first_point[0], self.first_point[1], event.x, event.y, fill='red', width=1, tags='line')
else:
# 第二次点击,完成线的绘制,记录第二个点,并重置first_point和points列表
self.canvas.coords(self.line1, self.first_point[0], self.first_point[1], event.x, event.y)
self.points = [self.first_point, (event.x, event.y)] # 更新points列表
self.first_point = None # 重置first_point
self.line1 = None # 重置线对象
self.update_zoom_canvas(event.x, event.y)
# 鼠标移动事件的回调方法
def on_canvas_motion(self, event):
if self.first_point:
if self.line1:
self.canvas.coords(self.line1, self.first_point[0], self.first_point[1], event.x, event.y)
# 当鼠标移动时,更新副画板的图像
if self.original_image is not None: # 确保已经加载了图像
self.update_zoom_canvas(event.x, event.y)
def update_zoom_canvas(self, x, y):
# 计算放大区域在原始图像中的坐标
zoom_x = int(x / self.scale) # 根据缩放比例计算原始图像的坐标
zoom_y = int(y / self.scale)
zoom_width = 50 # 定义放大区域的宽度为20像素
zoom_height = 50 # 定义放大区域的高度为20像素
# 确保放大区域不超出原始图像边界
left = max(0, zoom_x - zoom_width // 2)
top = max(0, zoom_y - zoom_height // 2)
right = min(zoom_x + zoom_width // 2, self.original_image.shape[1])
bottom = min(zoom_y + zoom_height // 2, self.original_image.shape[0])
# 裁剪放大区域
zoom_area = self.original_image[top:bottom, left:right]
# 调整裁剪区域的大小以适应zoom_canvas
zoom_area_resized = cv2.resize(zoom_area, (self.zoom_canvas.winfo_width(), self.zoom_canvas.winfo_height()), interpolation=cv2.INTER_AREA)
# 转换颜色空间并创建PhotoImage对象
canvas_image = Image.fromarray(cv2.cvtColor(zoom_area_resized, cv2.COLOR_BGR2RGB))
photo_image = ImageTk.PhotoImage(canvas_image)
# 删除zoom_canvas上的旧图像
self.zoom_canvas.delete("all") # 使用"all"来删除画布上的所有元素
# 在zoom_canvas上显示新的放大图像
self.zoom_canvas.create_image(0, 0, image=photo_image, anchor='nw')
self.zoom_canvas.image = photo_image
# 绘制小红叉
cross_size = 5 # 定义小红叉的臂长
cross_thickness = 2 # 定义小红叉的线宽
zoom_center_x = self.zoom_canvas.winfo_width() // 2
zoom_center_y = self.zoom_canvas.winfo_height() // 2
self.zoom_canvas.create_line(zoom_center_x - cross_size, zoom_center_y, zoom_center_x + cross_size, zoom_center_y, fill='red', width=cross_thickness)
self.zoom_canvas.create_line(zoom_center_x, zoom_center_y - cross_size, zoom_center_x, zoom_center_y + cross_size, fill='red', width=cross_thickness)
# 清除画布上点的方法
def clear_points(self):
self.canvas.delete('point')
self.canvas.delete('line')
self.points = []
self.first_point = None
if self.line1:
self.canvas.delete(self.line1)
self.line1 = None
# 计算两点间距离的方法
def calculate_distance(self):
if len(self.points) >= 2:
point1, point2 = self.points[:2]
distance = np.sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2)
messagebox.showinfo("Distance", f"两点间距离: {distance}px")
else:
messagebox.showerror("Error", "请至少选择两个点。")
# 计算结果的方法
def calculate_result(self):
try:
input_value = float(self.entry.get())
if len(self.points) >= 2 and self.scale != 1.0:
point1, point2 = self.points[:2]
distance_pixels = np.sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2)
self.result = (input_value / distance_pixels) * self.original_image.shape[1] * self.scale
self.result_label.config(text=f"图片宽度: {self.result:.2f}mm")
else:
messagebox.showerror("Error", "请至少选择两个点,并且图像已加载。")
except ValueError:
messagebox.showerror("Error", "输入无效,请输入一个数值。")
# 创建PDF文件的方法
def create_pdf(self):
try:
if self.result is None or self.result