我已经设置了这个窗口,在这里我将一个椭圆blit
到屏幕上。我想让椭圆完全白色,有一个平滑的边界。这看起来可以接受,但是当我将椭圆添加到白色背景时,椭圆的边界显示出来了。
import pygame
import cv2
import numpy as np
pygame.init()
# Set up the Pygame window
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width, screen_height))
def drawAACircle(surf, color, center, radius, width, angle):
circle_image = np.zeros((radius*2, radius*2, 4), dtype = np.uint8)
circle_image = cv2.ellipse(circle_image, (radius, radius), (radius-width, radius-width), (angle*-.5)-90 , 0, angle, (*color, 255), width, lineType=cv2.LINE_AA)
#draw it on the surface
surf.blit(pygame.image.frombuffer(circle_image.tobytes(), circle_image.shape[1::-1], "RGBA").convert_alpha(), (center[0]-radius, center[1]-radius))
# Wait for the user to close the window
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill((255,255,255))
drawAACircle(screen, (255,255,255), (screen_width/2,screen_height/2), 200, 20, 360)
# Update the display
pygame.display.flip()
当我将背景更改为全白色时,我注意到了边框:
我目前正在开发一个贴花工具,可以将多个椭圆堆叠在一起。我用copy()
刷新背景屏幕,如下所示:
def takeSnapshot():
global snapshot
snapshot = screen.copy()
def clearSnapshot():
global snapshot
snapshot = None
----
# Run the main loop
running = True
while running:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
running = False
# Clear the screen
if snapshot is None:
screen.fill((0,0,0))
else:
screen.blit(snapshot, (0,0))
我试过gfx.aapolygonicm的填充多边形,但是我不能得到像opencv椭圆一样清晰和干净的多边形。
如果有人知道另一种选择,我会很高兴听到,或者我可能忽略了一些东西,我可以得到全白色的opencv椭圆。
编辑:只是为了让它清楚,我选择了opencv椭圆的厚度选项,能够使一个弧形的形状,和光滑的外观。
2条答案
按热度按时间j8ag8udp1#
问题是抗锯齿不仅应用于Alpha通道,还应用于颜色通道(RGB通道)。基本上,这意味着颜色通道已经乘以Alpha通道。您必须使用“BLEND_PREMULTIPLED”模式正确混合此纹理(请参见
blit
):(我没有在这里显示结果,因为它全是白色的。)
m3eecexj2#
你确实有一个alpha通道......然而,OpenCV是哑的,不知道“alpha”是什么。它只是将每个通道的命令值与已经存在的值(黑色!)混合,你得到的是有效的预乘alpha。
你需要告诉pygame这件事,并希望它知道如何处理。
如果这不可能,你就必须去预乘,即除以,你的RGB通道和A通道。然后那些边界像素实际上是白色的,而不是已经与黑色混合,并且混合将正常工作,假设你可以用“straight alpha”语义混合。