使用python创建允许图像缩放和在其上绘制线条的应用程序的最佳方法是什么?
我一直在使用pygame来实现这一点,通过在非常大的表面(大小约15000)上绘制图像,并使用pygame.transform.scale(),它允许我进行缩放。此外,将使用convert_alpha()创建一个用于线条绘制的额外曲面,并将其设置为0 alpha。
这种方法的问题是,如果需要创建大尺寸的pygame.surface,则需要花费大量的时间和内存。此外,transform.scale()花费了很多时间。除直线外,还为图形类型创建了许多额外的曲面。
那么,有没有更好的方法来做同样的事情使用pyplay?还是用另一种方法做同样的事情?谢谢你。
缩放图像可以通过复制“基本图像”的一部分来实现,然后仅将较小的部分缩放到与窗口相同的大小。这样,代码只能保存基本图像、背景和子图像。您永远不会将整个图像缩放到缩放级别。
在下面的示例代码中,我使用“泛盒”的概念实现了这一点,泛盒是一个定义缩放部分大小和位置的PyGame矩形(Rect
)。实际上,它是一个长方形的“放大镜”。
代码的核心在该框的坐标和大小范围内复制背景,然后将其缩放为与窗口相同的大小,复制到“背景”图像:
window_size = ( WINDOW_WIDTH, WINDOW_HEIGHT )
zoom_image = pygame.Surface( ( pan_box.width, pan_box.height ) ) # new surface
zoom_image.blit( base_image, ( 0, 0 ), pan_box ) # copy base image
pygame.transform.scale( zoom_image, window_size, background ) # scale into the background
window.blit( background, ( 0, 0 ) )
pygame.display.flip()
这就是手术的关键。这工作得很好,因为它只是抓取原始图像的内容,无论盒子在哪里,并缩放它以适应窗口。左右平移或缩放只是移动平移盒,或者使其变大/变小的问题。
然而,为了保持核心代码的简单,示例中还有更多的代码,主要将泛框保持在图像中。事实上,大多数例子都是简单的检查,以确保我们不会出界。
图像复制和缩放是相对CPU昂贵的操作。因此,您将在代码中看到一些测试点,以确定是否需要执行某些操作。例如,如果平移框没有更改,我们不需要创建新的背景图像。如果平移框的大小没有改变,我们也不需要制作新的缩放图像。像这样的小检查可以大大提高代码的速度。
参考代码:
import pygame
import sys
# Window size
WINDOW_WIDTH = 300
WINDOW_HEIGHT = 300
WINDOW_SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
image_filename = None
PAN_BOX_WIDTH = 64
PAN_BOX_HEIGHT = 64
PAN_STEP = 5
def errorExit( message, code=1 ):
""" Write an error message to the console, then exit with an error code """
sys.stderr.write( message + "\n" )
sys.exit( code )
# The first argument is either the image filename
# or a "--help" request for help
# Did we get any arguments?
if ( len( sys.argv ) == 1 ):
errorExit( "Give an image Filename as an argument" )
else:
# Get image filename as first argument
for arg in sys.argv[1:]:
if ( arg in [ '-h', '--help', '-?', '/?' ] ):
errorExit( "Zooms an image, using arrow keys to pan\nGive an image Filename as an argument" )
# Use the first argument as the image source
image_filename = sys.argv[1]
sys.stdout.write( "Using [%s] as the image\n" % ( image_filename ) )
### PyGame initialisation
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption("Image Pan")
### Can we load the user's image OK?
try:
base_image = pygame.image.load( image_filename ).convert()
except:
errorExit( "Failed to open [%s]" % ( image_filename ) )
### Pan-position
background = pygame.Surface( ( WINDOW_WIDTH, WINDOW_HEIGHT ) ) # zoomed section is copied here
zoom_image = None
pan_box = pygame.Rect( 0, 0, PAN_BOX_WIDTH, PAN_BOX_HEIGHT ) # curent pan "cursor position"
last_box = pygame.Rect( 0, 0, 1, 1 )
### Main Loop
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Movement keys
# Pan-box moves up/down/left/right, Zooms with + and -
keys = pygame.key.get_pressed()
if ( keys[pygame.K_UP] ):
pan_box.y -= PAN_STEP
if ( keys[pygame.K_DOWN] ):
pan_box.y += PAN_STEP
if ( keys[pygame.K_LEFT] ):
pan_box.x -= PAN_STEP
if ( keys[pygame.K_RIGHT] ):
pan_box.x += PAN_STEP
if ( keys[pygame.K_PLUS] or keys[pygame.K_EQUALS] ):
pan_box.width += PAN_STEP
pan_box.height += PAN_STEP
if ( pan_box.width > WINDOW_WIDTH ): # Ensure size is sane
pan_box.width = WINDOW_WIDTH
if ( pan_box.height > WINDOW_HEIGHT ):
pan_box.height = WINDOW_HEIGHT
if ( keys[pygame.K_MINUS] ):
pan_box.width -= PAN_STEP
pan_box.height -= PAN_STEP
if ( pan_box.width < PAN_STEP ): # Ensure size is sane
pan_box.width = PAN_STEP
if ( pan_box.height < PAN_STEP ):
pan_box.height = PAN_STEP
# Ensure the pan-box stays within image
PAN_BOX_WIDTH = min( PAN_BOX_WIDTH, base_image.get_width() )
PAN_BOX_HEIGHT = min( PAN_BOX_HEIGHT, base_image.get_height() )
if ( pan_box.x < 0 ):
pan_box.x = 0
elif ( pan_box.x + pan_box.width >= base_image.get_width() ):
pan_box.x = base_image.get_width() - pan_box.width - 1
if ( pan_box.y < 0 ):
pan_box.y = 0
elif ( pan_box.y + pan_box.height >= base_image.get_height() ):
pan_box.y = base_image.get_height() - pan_box.height - 1
# Re-do the zoom, but only if the pan box has changed since last time
if ( pan_box != last_box ):
# Create a new sub-image but only if the size changed
# otherwise we can just re-use it
if ( pan_box.width != last_box.width or pan_box.height != last_box.height ):
zoom_image = pygame.Surface( ( pan_box.width, pan_box.height ) )
zoom_image.blit( base_image, ( 0, 0 ), pan_box ) # copy base image
window_size = ( WINDOW_WIDTH, WINDOW_HEIGHT )
pygame.transform.scale( zoom_image, window_size, background ) # scale into thebackground
last_box = pan_box.copy() # copy current position
window.blit( background, ( 0, 0 ) )
pygame.display.flip()
# Clamp FPS
clock.tick_busy_loop(60)
pygame.quit()
如果我把筹码拖离初始位置,它应该画一条线。当我移动筹码时,它应该总是画一条线。 这就是我所尝试的: 我将该代码放在芯片的ontouch listener中。您可以在此处下载该项目:https://www.dropbox.com/s/ggfbsbkaokj9vxi/CoachingBoard.rar?dl=0
问题内容: 我有一个用Java编写的Web应用程序(Spring,Hibernate / JPA,Struts2),用户可以在其中上传图像并将其存储在文件系统中。我想缩放这些图像,以使它们具有一致的大小,以便在网站上显示。哪些库或内置函数将提供最佳结果?在做出决定时,我将考虑以下标准: 免费/开源(基本) 易于实施 结果质量 性能 可执行文件的大小 问题答案: 看一下Java Image I /
我一直在做曼德尔布洛特集,并试图缩放,但缩放模式变得非常麻烦。当我缩放它完美地缩放,但图像大小减少到原来的一半。下次我再次缩放时,图片大小会增加,并试图跳过查看窗口。代码是c /opengl.在这里发布之前,我试图让我的代码变得干净一点。 执行时
我正在为必应地图开发一个使用Silverlight控件的应用程序。 我的意思是,如果我搜索意大利,map应该将mapview设置为包含整个意大利;如果我搜索威尼斯,变焦应该更高,向我展示整个城市;最后,如果我搜索一条街,我希望看到整条街(如果缩放不是太高自然)。 因为用户可以在搜索前放大/缩小,我需要重置缩放每次...但我没有找到一种方法来理解哪一个是最佳的缩放。
问题内容: 我开始使用Python(和OOP)进行编程,但是我对Fortran(90/95)和Matlab编程有丰富的经验。 我正在开发一个在tkinter环境上使用动画的小工具。该工具的目标是为多线动画(数组而不是数据向量)。下面是我的问题的一个简单示例。我不明白为什么这两种数据绘制方法的结果如此不同? 如果仅绘制“ dline”,则每条线将分别绘制并使用不同的颜色。如果仅绘制“ mline”,
我有以下代码应该在图像中绘制线条。我的代码是: 如果我编写,它实际上可以工作。但是我的数组很长并且来自一个输入。