首页 > 其他分享 >以鼠标位置进行图像非中心zoom

以鼠标位置进行图像非中心zoom

时间:2024-10-03 18:49:51浏览次数:10  
标签:鼠标 show image time zoom height width 图像

# 以鼠标位置进行图像非中心zoom
import tkinter as tk
from PIL import Image, ImageTk

image_show_width = 800
image_show_height = 600
window_width = image_show_width
window_height = image_show_height+120

root = tk.Tk()
root.geometry(f"{window_width}x{window_height}+800+50") 

# 创建标签用于显示图片    
label_imgshow = tk.Label(root, text="拖拽图片到这里", width=image_show_width, height=image_show_height, bg="lightgrey") 
label_imgshow.place(x = 0, y=0, width=image_show_width, height=image_show_height, bordermode = 'outside')


original_image = Image.open('test.png')
photo_image = ImageTk.PhotoImage(original_image)

# 更新Label中的图像
label_imgshow.config(image = photo_image)
label_imgshow.image = photo_image

width, height = original_image.size
print(width, height)
imgAdapting_display = original_image.resize((image_show_width, image_show_height), Image.LANCZOS)

zoom_value = 1.0

class Rect:
       def __init__(self, x = 0, y = 0, width = 0, height = 0):
           self.x = x
           self.y = y
           self.width = width
           self.height = height

class Point:
       def __init__(self, x = 0, y = 0):
           self.x = x
           self.y = y
import time
def timebegin():
    # 记录开始时间
    # global start_time
    start_time = time.time()
    return start_time

def timeend(code_blokc, start_time):
    # 记录结束时间
    # global end_time
    end_time = time.time()
    # 计算耗时(单位:秒)
    elapsed_time = end_time - start_time
    # print(code_blokc + f" 代码块耗时: {elapsed_time} 秒")

def zoom(event):
    # 1 imgAdapting_display用于控件显示的1x倍率图像,FOV为原始FOV, 大小与控件大小一致
    # 2 imgZoom是根据当前zoom_value,缩放的图像,FOV为原始FOV
    # 3 cropped_show_image 图像大小控件大小一致, FOV不确定
    start_time = timebegin()

    global zoom_value
    # 鼠标位置在图像显示控件的相对坐标
    # 获取鼠标位置或其他指定的缩放触发点位置
    ptMouse = Point(event.x, event.y)
    print("ptMouse ", ptMouse.x, ptMouse.y)
    scalestep = 1.21

    showRect = Rect(0,0,image_show_width,image_show_height)

    bIsImgSmallToDispCtrl = False
    if (event.delta  > 0):#放大图片
        if (zoom_value > 5):
            return
        else:
            zoom_value = zoom_value * scalestep;
    elif (event.delta < 0): #缩小图片
        zoom_value /= scalestep

    print("zoom_value ", zoom_value)

    zoom_width = int(image_show_width * zoom_value)
    zoom_height = int(image_show_height * zoom_value)

    timeend("mgAdapting_display.resize pre", start_time)

    start_time = timebegin()

    imgZoom = imgAdapting_display.resize((zoom_width, zoom_height), Image.LANCZOS)

    timeend("mgAdapting_display.resize", start_time)

    start_time = timebegin()

    #保持图像放大后,鼠标所指向的像素位置与原始像素位置一致
    showRect.x = zoom_value * ptMouse.x - ptMouse.x
    showRect.y = zoom_value * ptMouse.y - ptMouse.y

    showRect.width = image_show_width
    showRect.height = image_show_height
    
    if showRect.x < 0:
        showRect.x = abs(showRect.x)
        bIsImgSmallToDispCtrl = True
    if showRect.y < 0:
        showRect.y = abs(showRect.y)
        bIsImgSmallToDispCtrl = True

    showRect.x = int(showRect.x)
    showRect.y = int(showRect.y)

    print("bIsImgSmallToDispCtrl ", bIsImgSmallToDispCtrl)

    if bIsImgSmallToDispCtrl == True:
        # imgZoom的图像,此时属于显示图像已经比原始图像小了,然后进行放大,不需要进行crop,直接显示imgZoom
        cropped_show_image = imgZoom
    else:
        #imgZoom的图像比原始图像大,从imgZoom的图像中crop一块区域进行显示,crop的大小为显示控件的size
        left = showRect.x
        top = showRect.y
        width = showRect.width
        height = showRect.height
        crop_rect = (left, top, left + width, top + height)
        cropped_show_image = imgZoom.crop(crop_rect)

    timeend("cropped_show_image ", start_time)

    start_time = timebegin()

    # 更新Label中的图像
    photo_image = ImageTk.PhotoImage(cropped_show_image)
    label_imgshow.config(image = photo_image)
    label_imgshow.image = photo_image

    timeend("更新Label中的图像 ", start_time)


label_imgshow.bind("<MouseWheel>", zoom)
root.mainloop()

 

标签:鼠标,show,image,time,zoom,height,width,图像
From: https://www.cnblogs.com/adong7639/p/18445893

相关文章

  • VisionTS:基于时间序列的图形构建高性能时间序列预测模型,利用图像信息进行时间序列预测
    构建预训练时间序列模型时面临的主要挑战是什么?获取高质量、多样化的时间序列数据。目前构建基础预测模型主要有两种方法:迁移学习LLM:通过针对时间序列任务定制的微调或分词策略,重新利用预训练的大型语言模型(LLM),如GPT-4或Llama。从零训练:构建大规模时间序列数据集,并从头开始预训......
  • Java-图像处理秘籍-全-
    Java图像处理秘籍(全)原文:JavaImageProcessingRecipes协议:CCBY-NC-SA4.0一、JavaVM上的OpenCV几年前,在去上海的旅途中,我的一个非常好的朋友在OpenCV上给我买了一本大部头的书。它有大量的摄影操作、实时视频分析样本和非常有吸引力的深入解释,我迫不及待地想在我的本......
  • Recaptcha2 图像识别 API 对接说明
    Recaptcha2图像识别API对接说明本文将介绍一种Recaptcha2图像识别2API对接说明,它可以通过用户输入识别的内容和Recaptcha2验证码图像,最后返回需要点击的小图像的坐标,完成验证。接下来介绍下Recaptcha2图像识别API的对接说明。申请流程要使用API,需要先到Re......
  • 《OpenCV》—— 图像拼接
    下面是两张需要拼接的图片完整代码:importcv2importnumpyasnpimportsysdefcv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)defdetectAndDescribe(image):gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)descriptor=cv2.SIF......
  • OpenCV(图像对比度增强)
    目录1.直方图均衡化2.自适应直方图均衡化3.限制对比度自适应直方图均衡化4.线性对比度拉伸5.Gamma校正6.Retinex方法7.多尺度对比度增强8.方法选择与应用场景总结增强图像对比度是图像处理中的一个重要步骤,旨在提高图像中不同亮度区域之间的差异,使细节更加清晰和明显......
  • HS6621Cx 一款低功耗蓝牙SoC芯片 应用于键盘、鼠标和遥控器消费类产品动能世纪
    HS6621Cx是一款功耗优化的真正片上系统(SOC)解决方案,适用于低功耗蓝牙和专有2.4GHz应用。它集成了高性能、低功耗射频收发器,具有蓝牙基带和丰富的外设IO扩展。HS6621Cx还集成了电源管理功能,可提供高效的电源管理。它面向2.4GHz蓝牙低功耗系统、专有2.4GHz系统、人机接口设备(键盘......
  • [数据集][图像分类]骨关节炎严重程度分类数据集14038张4分类
    数据集类型:图像分类用,不可用于目标检测无标注文件数据集格式:仅仅包含jpg图片,每个类别文件夹下面存放着对应图片图片数量(jpg文件个数):14038分类类别数:4类别名称:[“grade0”,“grade2”,“grade3”,“grade4”]每个类别图片数:类别名称图片数grade08080grade23691grade31843gra......
  • OPENCV判断图像中目标物位置及多目标物聚类
    文章目录在最近的项目中,又碰到一个有意思的问题需要通过图像算法来解决。就是显微拍摄的到的医疗图像中,有时候目标物比较偏,也就是在图像的比较偏的位置,需要通过移动样本,将目标物置于视野正中央,然后再次进行拍摄。就类似于下面的图像:基于这个需求,在图像上就需要使......
  • 高点摄像山火烟雾检测数据集 共2890张图像,分辨率1920×1080,标注采用json格式,标注了每
    高点摄像山火烟雾检测数据集(并按照低、中详细标注烟雾浓度)。主要针对初期山火,任何野火检测系统的最重要目标是在火势扩大之前及时检测到火灾。在初期阶段,野火由非火焰性的燃烧烟雾组成,热量相对较低。在这个阶段识别火灾能够提供最佳的抑制机会。在这个阶段通常看不到火焰;因此,任......
  • 小白也能学会!unet医学图像分割(附源码和中文论文)
    本文主要介绍如何通过unet模型来训练自己的图像分割模型。即使没有编程经验,对照步骤执行也能训练模型。文中涉及的显微镜细胞图像分割数据集、模型训练代码(pytorch)、unet中文版论文等资源放于文末获取。目录1.论文摘要2.算法简述3.代码介绍4.数据准备5.模型训练6.模......