缩放/缩放平铺图像,将缩放点锚定到鼠标光标

时间:2017-03-09 15:46:45

标签: image python-2.7 pygame

我有一个项目,我正在为平铺图像设计图像查看器。每个图像区块为256x256像素。对于每个缩放级别,我将每个图像的大小增加5%。我通过将屏幕划分为与每个图像大小相同的图块来表示图块的放置。偏移用于将每个图像精确地放置在需要的位置。当缩放达到某个点(1.5)时,我切换到一个新的图像层,它总共具有比前一个图像更高的分辨率。缩放方法本身如下所示:

def zoomer(self, mouse_pos, zoom_in): #(tuple, bool)

    x, y = mouse_pos
    x_tile, y_tile = x / self.tile_size, y / self.tile_size
    old_scale = self.scale
    if self.scale > 0.75 and self.scale < 1.5:
        if zoom_in:
            self.scale += SCALE_STEP # SCALE_STEP = 5% = 0.05
            ratio = (SCALE_STEP + 1)
        else:
            self.scale -= SCALE_STEP
            ratio = 1 / (SCALE_STEP + 1)
    else:
        if zoom_in:
            self.zoom += 1
            self.scale = 0.8
            ratio = (SCALE_STEP + 1)
        else:
            self.zoom -= 1
            self.scale = 1.45
            ratio = 1 / (SCALE_STEP + 1)

    # Results in x/y lengths of the relevant full image
    x_len = self.size_list[self.levels][0] / self.power()
    y_len = self.size_list[self.levels][1] / self.power()
    # Removing extra pixel if present
    x_len = x_len - (x_len % 2)
    y_len = y_len - (y_len % 2)
    # The tile's picture coordinates
    tile_x = self.origo_tile[0] + x_tile
    tile_y = self.origo_tile[1] + y_tile
    # The mouse's picture pixel address
    x_pic_pos = (tile_x * self.tile_size) - 
                 self.img_x_offset + (x % self.tile_size)
    y_pic_pos = (tile_y * self.tile_size) - 
                 self.img_y_offset + (y % self.tile_size)
    # Mouse percentile placement within the image
    mouse_x_percent = (x_pic_pos / old_scale) / x_len
    mouse_y_percent = (y_pic_pos / old_scale) / y_len
    # The mouse's new picture pixel address
    new_x = (x_len * self.scale) * mouse_x_percent
    new_y = (y_len * self.scale) * mouse_y_percent
    # Scaling tile size
    self.tile_size = int(TILE_SIZE * self.scale)
    # New mouse screen tile position
    new_mouse_x_tile = x / self.tile_size
    new_mouse_y_tile = y / self.tile_size
    # The mouse's new tile address
    new_tile_x = new_x / self.tile_size
    new_tile_y = new_y / self.tile_size
    # New tile offsets
    self.img_x_offset = (x % self.tile_size) - int(new_x % self.tile_size)
    self.img_y_offset = (y % self.tile_size) - int(new_y % self.tile_size)
    # New origo tile
    self.origo_tile = (int(new_tile_x) - new_mouse_x_tile,
                       int(new_tile_y) - new_mouse_y_tile)

现在,由此产生的问题是mouse_.._percent变量似乎永远不会与实际位置相匹配。出于测试目的,我使用位于屏幕中间的鼠标位置来提供方法,并且图片也位于中间。因此,在完美的世界中,生成的mouse_.._percent变量应始终等于50%。对于第一级,它确实如此,但在缩放时会很快消失。当我到达第一个缩放断点(self.scale == 1.5)时,该位置已移至x = 48%y = 42%self.origo_tile是一个元组,包含要在屏幕图块上绘制的图块的x / y坐标(0,0)

我已经盯着这看了几个小时,但看不到找到它的补救措施......

1 个答案:

答案 0 :(得分:0)

该计划如何运作:

我很抱歉我没有足够的时间将其应用到您的代码中,但我编写了以下缩放模拟器。该程序允许您多次缩放相同的“图像”,并输出将出现在屏幕中央的图像点,以及显示的图像数量。

代码:

from __future__ import division #double underscores, defense against the sinister integer division

width=256 #original image size
height=256
posx=128 #original display center, relative to the image
posy=128

while 1:
    print "Display width: ", width
    print "Display height: ", height
    print "Center X: ", posx
    print "Center Y: ", posy
    anchx = int(raw_input("Anchor X: "))
    anchy = int(raw_input("Anchor Y: "))
    zmag = int(raw_input("Zoom Percent (0-inf): "))
    zmag /= 100 #convert from percent to decimal
    zmag = 1/zmag
    width *= zmag
    height *= zmag
    posx = ((anchx-posx)*zmag)+posx
    posy = ((anchy-posy)*zmag)+posy

样本输出:

如果此程序输出以下内容:

Display width: 32.0
Display height: 32.0
Center X: 72.0
Center Y: 72.0

说明:

这意味着放大屏幕仅显示图像的一部分,该部分为32x32像素,该部分的中心位于坐标(72,72)处。这意味着在两个轴上,它在该特定示例中显示图像的像素56-88。

解决方案/结论:

稍微使用该程序,看看是否可以将其实现到您自己的代码中。请记住,不同的程序以不同的方式移动中心X和Y,如果您不喜欢它已经如何工作,则更改我给出的程序(尽管您可能会这样做,这是一种常见的方式)。快乐的编码!