如何放大和缩小图像pygame并使用鼠标位置作为缩放中心

2024-04-13

我遇到了无法解决的 PyGame 问题。所以: 我的想法是我有一张可以放大/缩小的地图。放大效果很好。但缩小后显示图片的其余部分已被删除,现在仅存在之前在窗口上可见的图像部分。 这是我的代码:

import pygame
from pygame.locals import *
import os

class App:
    def __init__(self):
        self.running = True
        self.size = (800,600)

         #create window
        self.window = pygame.display.set_mode(self.size, pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)

        #create map
        currentdir = os.path.dirname(os.path.realpath(__file__))
        imagedir = currentdir+'/images/europe.png'
        self.map =  pygame.image.load(imagedir)
        self.maprect = self.map.get_rect()
        self.mapsurface = pygame.Surface(self.size)
        self.mapsurface.blit(pygame.transform.scale(self.map,(self.size)),(0,0))
        self.window.blit(self.mapsurface,(0,0))
        self.scale = 1

        #create window
        pygame.display.flip()

    def on_init(self):
        self.country = Country()

    def on_cleanup(self):
        pygame.quit()
        
    def check_event(self,event):
        if event.type == pygame.QUIT:
            self.running = False
        elif event.type == pygame.VIDEORESIZE:
            self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
            self.window.blit(pygame.transform.scale(self.map,(event.dict['size'])),(0,0))
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4:
                zoom = 2
                wnd_w,wnd_h = self.window.get_size()
                zoom_size = (round(wnd_w/zoom), round(wnd_h/zoom))
                zoom_area = pygame.Rect(0,0, *zoom_size)
                pos_x,pos_y = pygame.mouse.get_pos()
                zoom_area.center = (pos_x, pos_y)
                zoom_surf = pygame.Surface(zoom_area.size)
                zoom_surf.blit(self.window, (0, 0), zoom_area)
                zoom_surf = pygame.transform.smoothscale(zoom_surf, (wnd_w, wnd_h))
                self.window.blit(zoom_surf, (0, 0))

            elif event.button == 5:
                zoom = 0.5
                wnd_w,wnd_h = self.window.get_size()
                zoom_size = (round(wnd_w/zoom), round(wnd_h/zoom))
                zoom_area = pygame.Rect(0,0,*zoom_size)
                pos_x,pos_y = pygame.mouse.get_pos()
                zoom_area.center = (pos_x, pos_y)
                zoom_surf = pygame.Surface(zoom_area.size)
                zoom_surf.blit(self.window, (0, 0), zoom_area)
                zoom_surf = pygame.transform.smoothscale(zoom_surf, (wnd_w, wnd_h))
                self.window.blit(zoom_surf, (0, 0))
            pygame.display.flip()

        pygame.display.update()
    def on_execute(self):
        while self.running == True:
            for event in pygame.event.get():
                self.check_event(event)
        self.on_cleanup()

class Country(App):
    def __init__(self):
        super().__init__()
    

start = App()
start.on_init()
start.on_execute()

以下是我的问题的截图:

到目前为止,一切都很好:

放大效果很好:

缩小会导致以下情况:


您需要扩展并blit缩放时的原始图像。使用属性maprect定义地图的缩放尺寸和相对位置。添加一个方法blit可以缩放和位图传输地图的地图。在类的构造函数中使用该方法App:

class App:
    def __init__(self):
        # [...]

        self.map =  pygame.image.load(imagedir)
        self.maprect = self.map.get_rect(center = self.window.get_rect().center)
        self.blitmap()

        #create window
        pygame.display.flip()

    def blitmap(self):
        self.mapsurface = pygame.transform.smoothscale(self.map, self.maprect.size)
        self.window.fill(0)
        self.window.blit(self.mapsurface, self.maprect)

    # [...]

当图像缩放时,计算新的映射矩形(self.maprect) 并再次调用该方法:

class App:
    # [...]

    def check_event(self,event):
        if event.type == pygame.QUIT:
            self.running = False

        elif event.type == pygame.VIDEORESIZE:
            self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
            self.blitmap()

        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4 or event.button == 5:
                zoom = 2 if event.button == 4 else 0.5
                mx, my = event.pos
                left   = mx + (self.maprect.left - mx) * zoom
                right  = mx + (self.maprect.right - mx) * zoom
                top    = my + (self.maprect.top - my) * zoom
                bottom = my + (self.maprect.bottom - my) * zoom
                self.maprect = pygame.Rect(left, top, right-left, bottom-top)
                self.blitmap()

也可以看看缩放和缩放窗口 https://github.com/Rabbid76/PyGameExamplesAndAnswers/blob/master/documentation/pygame/pygame_display_resize_and_scroll.md#scale-and-zoom-window


完整示例:

repl.it/@Rabbid76/PyGame-ZoomInAndOut

import pygame
from pygame.locals import *
import os

class App:
    def __init__(self):
        self.running = True
        self.size = (800,600)

         #create window
        self.window = pygame.display.set_mode(self.size, pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)

        #create map
        currentdir = os.path.dirname(os.path.realpath(__file__))
        imagedir = currentdir+'/images/europe.png'
        self.map =  pygame.image.load(imagedir)
        self.maprect = self.map.get_rect(center = self.window.get_rect().center)
        self.blitmap()
        
        #create window
        pygame.display.flip()

    def blitmap(self):
        self.mapsurface = pygame.transform.smoothscale(self.map, self.maprect.size)
        self.window.fill(0)
        self.window.blit(self.mapsurface, self.maprect)

    def on_init(self):
        self.country = Country()

    def on_cleanup(self):
        pygame.quit()
        
    def check_event(self,event):
        if event.type == pygame.QUIT:
            self.running = False
        
        elif event.type == pygame.VIDEORESIZE:
            self.window = pygame.display.set_mode(event.dict['size'], pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
            self.blitmap()
        
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4 or event.button == 5:
                zoom = 2 if event.button == 4 else 0.5
                mx, my = event.pos
                left   = mx + (self.maprect.left - mx) * zoom
                right  = mx + (self.maprect.right - mx) * zoom
                top    = my + (self.maprect.top - my) * zoom
                bottom = my + (self.maprect.bottom - my) * zoom
                self.maprect = pygame.Rect(left, top, right-left, bottom-top)
                self.blitmap()

        pygame.display.update()

    def on_execute(self):
        while self.running == True:
            for event in pygame.event.get():
                self.check_event(event)
        self.on_cleanup()

class Country(App):
    def __init__(self):
        super().__init__()
    

start = App()
start.on_init()
start.on_execute()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何放大和缩小图像pygame并使用鼠标位置作为缩放中心 的相关文章

  • 将 transaction.commit_manually() 升级到 Django > 1.6

    我继承了为 Django 1 4 编写的应用程序的一些代码 我们需要更新代码库以使用 Django 1 7 并最终更新到 1 8 作为下一个长期支持版本 在一些地方它使用旧风格 transaction commit manually and
  • TensorFlow:带有轴选项的 bincount

    在 TensorFlow 中 我可以使用 tf bincount 获取数组中每个元素的计数 x tf placeholder tf int32 None freq tf bincount x tf Session run freq feed
  • NumPy linalg.eig

    我有这个烦人的问题 但我还没有弄清楚 我有一个矩阵 我想找到特征向量 所以我写 val vec np linalg eig mymatrix 然后我得到了 vec 我的问题是 当我小组中的其他人对相同的矩阵 mymatrix 做同样的事情时
  • 在 python 3 中使用子进程

    我使用 subprocess 模块在 python 3 中运行 shell 命令 这是我的代码 import subprocess filename somename py in practical i m using a real fil
  • 将二维数组放入 Pandas 系列中

    我有一个 2D Numpy 数组 我想将其放入 pandas 系列 而不是 DataFrame 中 gt gt gt import pandas as pd gt gt gt import numpy as np gt gt gt a np
  • 如何在VIM中设置文件的正确路径?

    每当我击中 pwd在 vim 中命令总是返回路径C Windows system32 即使我在桌面上的 Python 文件中 所以每当我跑步时 python 命令返回 python can t open file Users myname
  • Python tkinter.filedialog Askfolder 干扰 clr

    我主要在 Spyder 中工作 构建需要弹出文件夹或文件浏览窗口的脚本 下面的代码在spyder中完美运行 在 Pycharm 中 askopenfilename工作良好 同时askdirectory什么都不做 卡住了 但是 如果在调试模式
  • 如何在Python中高效地添加稀疏矩阵

    我想知道如何在Python中有效地添加稀疏矩阵 我有一个程序 可以将大任务分解为子任务 并将它们分配到多个 CPU 上 每个子任务都会产生一个结果 一个 scipy 稀疏矩阵 格式为 lil matrix 稀疏矩阵尺寸为 100000x50
  • 芹菜中未处理的异常冻结了工人

    我通过 redis 后端在 docker 中运行 celery 我有 芹菜搅拌容器 芹菜工人容器 Redis容器 celery 工作容器生成 6 个工作进程 如果 celery 任务遇到异常 工作人员 所有工作人员 将停止使用作业 我尝试稍
  • ValueError:不支持连续[重复]

    这个问题在这里已经有答案了 我正在使用 GridSearchCV 进行线性回归的交叉验证 不是分类器也不是逻辑回归 我还使用 StandardScaler 对 X 进行标准化 我的数据框有 17 个特征 X 和 5 个目标 y 观察 约11
  • Alembic:如何迁移模型中的自定义类型?

    My User模型是 class User UserMixin db Model tablename users noinspection PyShadowingBuiltins uuid Column uuid GUID default
  • 如何从 JSON 响应重定向?

    所以我尝试使用 Flask 和 Javascript 上传器 Dropzone 上传文件并在上传完成后重定向 文件上传正常 但在烧瓶中使用传统的重定向 return redirect http somesite com 不执行任何操作 页面
  • Django - 提交具有同一字段多个输入的表单

    预警 我对 Django 以及一般的 Web 开发 非常陌生 我使用 Django 托管一个基于 Web 的 UI 该 UI 将从简短的调查中获取用户输入 通过我用 Python 开发的一些分析来提供输入 然后在 UI 中呈现这些分析的可视
  • 从 python 检测 macOS 中的暗模式

    我正在编写一个 PyQt 应用程序 我必须添加一个补丁 以便在启用暗模式的 Macos 上可以读取字体 app QApplication Fix for the font colours on macos when running dark
  • falcon,AttributeError:“API”对象没有属性“create”

    我正在尝试测试我的猎鹰路线 但测试总是失败 而且看起来我把所有事情都做对了 my app py import falcon from resources static import StaticResource api falcon API
  • Python对象初始化性能

    我只是做了一些快速的性能测试 我注意到一般情况下初始化列表比显式初始化列表慢大约四到六倍 这些可能是错误的术语 我不确定这里的行话 例如 gt gt gt import timeit gt gt gt print timeit timeit
  • 计算互相关函数?

    In R 我在用ccf or acf计算成对互相关函数 以便我可以找出哪个移位给我带来最大值 从它的外观来看 R给我一个标准化的值序列 Python 的 scipy 中是否有类似的东西 或者我应该使用fft模块 目前 我正在这样做 xcor
  • bs4 `next_sibling` VS `find_next_sibling`

    我在使用时遇到困难next sibling 并且类似地与next element 如果用作属性 我不会得到任何返回 但如果用作find next sibling or find next 然后就可以了 来自doc https www cru
  • 操作错误:(sqlite3.OperationalError) SQL 变量太多,同时将 SQL 与数据帧一起使用

    我有一个熊猫数据框 如下所示 activity User Id 0 VIEWED MOVIE 158d292ec18a49 1 VIEWED MOVIE 158d292ec18a49 2 VIEWED MOVIE 158d292ec18a4
  • [cocos2d-x]当我尝试在 Windows 10 中运行“python android-build.py -p 19 cpp-tests”时出现错误

    当我尝试运行命令时python android build p cpp tests 我收到如图所示的错误 在此之前 我收到了另一条关于 Android SDK Tools 版本兼容性的错误消息 所以 我只是将 sdk 版本从 26 0 0

随机推荐

  • 什么时候应该调用 glGetError?

    glLoadIdentity http www opengl org sdk docs man xhtml glLoadIdentity xml says GL INVALID OPERATION如果生成glLoadIdentity之间执行
  • Visual Studio 代码覆盖率未显示所有程序集

    我的 SLN 文件中有 20 个项目 我正在通过测试资源管理器运行单元测试并生成代码覆盖率 只有八个项目出现在报道中 见屏幕截图 我正在使用一个 runsettings 文件 其中注释掉了所有 标记的内容 如下所示
  • 忽略空格的查询

    运行查询以便字段中的空格是最好的方法是什么 被忽视 例如 以下查询 SELECT FROM mytable WHERE username JohnBobJones SELECT FROM mytable WHERE username Joh
  • 查找 GIT 中具有特定单词/行的最新提交

    如果我有一个包含最新提交的文件 如下所示 class A String name Mary 在特定的提交中 String name Mary 被更改为String name Bob 问题是 这一行已经被修改了几次 有一次是 John 另一个
  • 上传数据到Meteor/Mongodb

    我有一个 Meteor 应用程序 想将数据 从 csv 上传到流星集合 我已经发现 解决方案 例如集合fs https github com CollectionFS Meteor CollectionFS 处理文件上传 方法用于直接上传
  • 如何在 Windows Azure 上部署 Java 应用程序

    您好 我是一名计算机科学专业三年级学生 我已经在 netbeans 上用 java 创建了一个三年级项目 现在我想将其部署到带有 windows azure 的虚拟机上 重点是 我希望能够在任何连接到互联网的计算机上使用这个应用程序 只需访
  • 单链打印C++

    我正在尝试以 1 2 3 4 etc 格式选择我的链 您可以在下面找到头文件 其中包含节点的布局 我只是对如何循环浏览列表以打印项目感到困惑 任何指导将不胜感激 set h using namespace std include
  • Go:在二进制文件中嵌入静态文件

    这可能是一个非常业余的问题 我正在尝试将静态文件嵌入到二进制文件中 即 html 我该怎么做https github com jteeuwen go bindata https github com jteeuwen go bindata
  • front() 和 begin() 之间的区别

    两者有什么区别front and begin 许多 STL 容器中出现的函数 begin http www cplusplus com reference stl list begin 返回一个可用于迭代集合的迭代器 而front http
  • OnItemCLickListener 在列表视图中不起作用

    Activity班级代码 conversationList ListView findViewById android R id list ConversationArrayAdapter conversationArrayAdapter
  • 从干草堆索引中删除对象

    我使用 django 删除一条记录 r model objects get id 1 r delete 现在我想从索引中删除记录而不重新索引 如何 我无法让remove object工作并且干草堆文档 http django haystac
  • 从 Windows 服务打印 pcl 文件的 LPR 命令不起作用(现在是托盘应用程序)

    我已经四处寻找可能的解决方案和解释一段时间了 但我找不到任何东西 以下命令正在从 Windows 服务运行 如果直接在 cmd 中使用 相同的命令也可以运行 它不会返回任何错误或与此相关的任何其他内容 System Diagnostics
  • 每 5 分钟自动运行一次 Selenium 测试

    有没有办法自动执行每五分钟运行一次的硒测试 如果您已将测试打包为可执行文件 最简单的方法可能是运行 CRON 作业或 Windows 计划任务 也就是说 Hudson 或另一个持续集成系统 几乎肯定是更好的长期策略
  • 日期格式:Android 联系人生日周年纪念日

    处理联系人生日和周年纪念日 我得到这样的详细信息和生日 12 2 2012 或 12 2 2012 或 12 02 2012 或 2 12 12 问题 所有三星手机的日期格式都相同吗 如果是 日期格式是什么 猜测不适用于所有 Android
  • sbt 中未解决的依赖关系

    运行我的sbt构建 我得到以下内容未解决的依赖关系 warn warn UNRESOLVED DEPENDENCIES warn warn com typesafe play sbt link 2 2 0 not found warn co
  • t-SQL 授予表删除和创建权限

    如何授予某些用户仅在 VB net 2005 Win 应用程序访问的 SQL 2005 数据库中删除和创建单个表的权限 有些文章建议授予表的控制权 但我无法做到这一点 如果您认为这是正确的方法 您能告诉我正确的语法吗 您不能在单个表上分配
  • 密码重置链接未重定向到网站

    我正在尝试使用 django Rest 框架在我的 React 应用程序中实现密码重置功能 我正在使用rest auth Issue 当我尝试从网站重置密码后 它会将密码重置链接发送到电子邮件 但单击该链接后 它会重定向到 DRF 默认密码
  • 如何从颤振路径中获取音频元数据?

    我有音频文件的路径 如 sdcard music ABC mp3 如何从该路径获取其他详细信息 例如专辑 艺术家 持续时间等 如果您正在使用颤动声音 https pub dev packages flutter sound 有一些实用方法可
  • 使用 Array.every 缩小数组类型的联合

    我有一个变量 其类型是不同数组类型的联合 我想将其类型缩小为该联合的单个成员 这样我就可以为每种类型运行适当的代码 使用Array every https developer mozilla org en US docs Web JavaS
  • 如何放大和缩小图像pygame并使用鼠标位置作为缩放中心

    我遇到了无法解决的 PyGame 问题 所以 我的想法是我有一张可以放大 缩小的地图 放大效果很好 但缩小后显示图片的其余部分已被删除 现在仅存在之前在窗口上可见的图像部分 这是我的代码 import pygame from pygame