如何" Crop" Pygame中的旋转图像

时间:2016-05-28 08:26:39

标签: python python-3.x rotation pygame

问题:

我试图在Pygame中绘制旋转图像,但我只想显示图像的上半部分。我已设法旋转图像,使其正确居中,但我无法裁剪它只显示上半部分。

我认为这是由于矩形被旋转,当我使用surface.subsurface()将其裁剪到某个矩形时,裁剪的部分有一个"弹跳"效果随着矩形变大和变小,取决于旋转角度

代码:

def updateTime(screen, hudtimecircle, time):
    center = (200, 200)                                        # The center of where the rotated image will be drawn
    amount = time                                              # just a number 1-360

    newcircle = pygame.transform.rotate(hudtimecircle, amount) # The rotated version of the un-rotated "hudtimecircle" image
    newrect = newcircle.get_rect()                             # The rect of the rotated image
    newrect.center = center                                    # Setting the middle of the rotated rect to the point I want to be the center

    crop = (0, 0, 120, 60)                                     # An area that I want to be left when I "Crop", This is the part that needs fixing
    cropped = newcircle.subsurface(crop)                       # The cropped part of the rotated image, I want/need this to only give the top half of the image.
    screen.blit(cropped, newrect.topleft)                      # Drawing the rotated image with it's middle point where the variable "center" says.

我尝试过相对于旋转的矩形进行裁剪,如下所示:

crop = (newrect.topleft[0], newrect.topleft[1], newrect.midright[0], newrect.midright[1])

然而,这不起作用并返回ValueError: subsurface rectangle outside surface area,因为每个或某些点都在图像区域之外。

其他信息:

图像hudtimecircle是120px * 120px,是一个圆形图像,背景透明,我只想在旋转后绘制圆圈的前60px。

amounttime只是1到360之间的数字,我有这条线,因为我打算稍后再做一些事情。

我无法在图片下半部分的顶部插入另一张图片,以便"裁剪"因为在这个图像需要放置的地方有许多不同的东西。

我看过:

https://www.reddit.com/r/learnpython/comments/3xeu4c/image_cropping_with_pygame/ http://blog.tankorsmash.com/?p=128
pygame rotation around center point
还有一些其他问题并不太重要。

为了澄清,我的问题不是旋转图像,或保持旋转的图像居中。问题是我只需要显示旋转的居中图像的上半部分。

如果还有其他需要的信息,我很乐意提供。

2 个答案:

答案 0 :(得分:2)

这是你想要达到的效果吗?您必须在每次旋转后计算新的裁剪位置,因为旋转的图像的大小始终在变化。在左上角,您可以看到父图像/曲面的变化情况。

import sys
import pygame as pg


def main():
    pg.init()
    screen = pg.display.set_mode((320, 240))
    clock = pg.time.Clock()
    done = False
    bg_color = pg.Color(50, 80, 120)
    # Create the original image that we use for the rotation
    # to avoid visual degeneration.
    orig_img = pg.Surface((100, 100))
    orig_img.fill((20, 50, 130))
    pg.draw.circle(orig_img, pg.Color('springgreen2'), (30, 30), 30)
    pg.draw.circle(orig_img, pg.Color('lightgoldenrod3'), (60, 60), 30)
    pg.draw.rect(orig_img, pg.Color('black'), (48, 0, 4, 100))
    pg.draw.rect(orig_img, pg.Color('black'), (0, 48, 100, 4))
    rect = orig_img.get_rect(topleft=(30, 30))

    angle = 0

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True

        angle += 1
        # Rotate the image.
        img = pg.transform.rotate(orig_img, angle)
        rect = img.get_rect(center=rect.center)
        # Calculate new crop position. Half of the new
        # width & height minus half of the original dimensions.
        x, y = rect.width/2 - 50, rect.height/2 - 50
        sub = img.subsurface((x, y, 100, 50))

        screen.fill(bg_color)

        screen.blit(img, rect)
        screen.blit(sub, (150, 150))

        pg.display.flip()
        clock.tick(30)


if __name__ == "__main__":
    main()
    pg.quit()
    sys.exit()

答案 1 :(得分:1)

你必须将crop变量放在括号中,所以:

您的代码:

crop = (0, 0, 120, 60)
cropped = newcircle.subsurface(crop)

正确的代码:

crop = (0, 0, 120, 60)
cropped = newcircle.subsurface((crop))

如果有效,请注意我。