当前位置: 首页 > 面试题库 >

在pygame中在透明表面上呈现抗锯齿文本

计燕七
2023-03-14
问题内容

我在做一个函数,它接受一个字符串,把它分成几行
返回一个曲面,其中每一行渲染在前一行的下方。
例如:
第1行\n第2行
渲染为:

Line1
Line2

不管怎样,我的问题是我不能返回一个完全透明的表面
调用函数。我试过使用颜色键,但它不适用于
抗锯齿文本。有办法吗?谢谢你的回答。
我的代码:(当前在文本周围留下一个丑陋的紫色阴影)

def render_message(messages):
    surfaces = []
    height = 0
    max_width = 0

    for message in messages.split('\n'):
        surf = FONT.render(message, True, (0, 0, 0))
        surfaces.append(surf)
        height += surf.get_height() + 5
        if surf.get_width() > max_width:
            max_width = surf.get_width()

    result = pygame.Surface((max_width, height))
    result.fill((255, 0, 255))
    result.set_colorkey((255, 0, 255))

    top = 0
    for surface in surfaces:
        result.blit(surface, (max_width/2-surface.get_width()/2, top))
        top += surface.get_height() + 5

    return result

问题答案:

发布了第二个答案,因为这更复杂,人们可能想看看
两者都有

  • 1 , 2 decrease/increase font size
  • space toggle BG

I left text wrapping out. Edit parse_text() to create a list of text you
want.

import pygame
from pygame import Surface
from pygame.locals import *
# Todo: remove font object from TextLine() , to TextWall(). Then share a list of font's with any line.

"""Example of multi-line text class, with alpha transparency."""
lorem = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed aliquet
tellus eros, eu faucibus dui. Phasellus eleifend, massa id ornare sodales, est urna
congue tellus, vitae varius metus nunc non enim. Mauris elementum, arcu vitae tempor euismod, justo turpis malesuada est, sed dictum nunc nulla nec mauris. Cras felis eros, elementum vitae sollicitudin in, elementum et augue. Proin eget nunc at dui congue pretium. Donec ut ipsum ut lacus mollis tristique. In pretium varius dui eu dictum.

Proin pulvinar metus nec mi semper semper. Pellentesque habitant morbi tristique
senectus et netus et malesuada fames ac turpis egestas. Proin in diam odio. Vestibulum
at neque sed ante sodales eleifend quis id dui. Mauris sollicitudin, metus a semper consectetur,
est lectus varius erat, sit amet ultrices tortor nisi id justo. Aliquam elementum vestibulum dui ut auctor. Mauris commodo sapien vitae augue tempus sagittis. Morbi a nibh lectus, sed porta nibh. Donec et est ac dui sodales aliquet tristique et arcu. Nullam enim felis, posuere vel rutrum eu, euismod a purus. Morbi porta cursus libero, id rutrum elit lacinia vitae.

In condimentum ultrices ipsum, ut convallis odio egestas et. Cras at egestas elit. Morbi
quis neque ligula. Sed tempor, sem at fringilla rhoncus, diam quam mollis nisi, vitae semper
mi massa sit amet tellus. Vivamus congue commodo ornare. Morbi et mi non sem malesuada rutrum. Etiam est purus, interdum ut placerat sit amet, tempus eget eros. Duis eget augue quis diam facilisis blandit. Ut vulputate adipiscing eleifend. """

class TextLine(object):
    # Manages drawing and caching a single line of text
    # You can make font size, .color_fg etc be properties so they *automatically* toggle dirty bool.
    def __init__(self, font=None, size=16, text="hi world"):        
        self.font_name = font
        self.font_size = size
        self.color_fg = Color("white")
        self.color_bg = Color("gray20")

        self._aa = True 
        self._text = text                
        self.font = pygame.font.Font(font, size)
        self.screen = pygame.display.get_surface()

        self.dirty = True
        self.image = None
        self._render()

    def _render(self):
        # render for cache
        """no AA = automatic transparent. With AA you need to set the color key too"""
        self.dirty = False        
        self.image = self.font.render(self._text, self.aa, self.color_fg)            
        self.rect = self.image.get_rect()

    def draw(self):
        # Call this do draw, always prefers to use cache
        if self.dirty or (self.image is None): self._render()
        self.screen.blit(self.image, self.rect)

    @property
    def text(self):
        return self._text

    @text.setter
    def text(self, text):
        self.dirty = True
        self._text = text

    @property
    def aa(self): return self._aa

    @aa.setter
    def aa(self, aa):
        self.dirty = True
        self._aa = aa

class TextWall(object):
    # Manages multiple lines of text / paragraphs.
    def __init__(self, font=None, size=16):
        self.font = font
        self.font_size = size        
        self.offset = Rect(20,20,1,1) # offset of whole wall

        self.screen = pygame.display.get_surface()
        self.dirty = True
        self.text_lines = []
        self._text_paragraph = "Empty\nText"
        self._render()

    def _render(self):
        # render list 
        self.dirty = False
        self.text_lines = [ TextLine(self.font, self.font_size, line) for line in self._text_paragraph ]

        # offset whole paragraph
        self.text_lines[0].rect.top = self.offset.top

        # offset the height of each line
        prev = Rect(0,0,0,0)        
        for t in self.text_lines:
            t.rect.top += prev.bottom
            t.rect.left = self.offset.left
            prev = t.rect

    def parse_text(self, text):
        # parse raw text to something usable
        self._text_paragraph = text.split("\n")
        self._render()

    def draw(self):
        # draw with cached surfaces    
        if self.dirty: self._render()
        for text in self.text_lines: text.draw()

    @property
    def font_size(self):
        return self._font_size

    @font_size.setter
    def font_size(self, size):
        self.dirty = True
        self._font_size = size

    @property
    def text(self):
        return self._text_paragraph

    @text.setter
    def text(self, text_paragraph):
        self.dirty = True
        self.parse_text(text_paragraph)

class Game():
    done = False
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode ((640,480))
        self.text = Surface([200,100])

        self.text_wall = TextWall()
        self.toggle_bg = True

        self.text_wall.parse_text(lorem)

    def loop(self):
        while not self.done:
            self.handle_events()
            self.draw()

    def draw(self):
        if self.toggle_bg: bg = Color("gray60")
        else: bg = Color("gray20")

        self.screen.fill(bg)        
        self.text_wall.draw()        
        pygame.display.update()

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT: self.done = True

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE: self.done = True                
                elif event.key == K_SPACE: self.toggle_bg = not self.toggle_bg
                elif event.key == K_1: self.text_wall.font_size -= 3
                elif event.key == K_2: self.text_wall.font_size += 3

if __name__ == "__main__":
    g = Game()
    g.loop()


 类似资料:
  • 在学习渲染的旅途中,你可能会时不时遇到模型边缘有锯齿的情况。这些锯齿边缘(Jagged Edges)的产生和光栅器将顶点数据转化为片段的方式有关。在下面的例子中,你可以看到,我们只是绘制了一个简单的立方体,你就能注意到它存在锯齿边缘了: 可能不是非常明显,但如果你离近仔细观察立方体的边缘,你就应该能够看到锯齿状的图案。如果放大的话,你会看到下面的图案: 这很明显不是我们想要在最终程序中所实现的效果

  • 目前我正在使用JavaFX开发一个2D游戏,游戏是像素艺术。不幸的是,像素艺术是模糊的,这是由抗锯齿引起的。 有没有办法在JavaFX画布上禁用抗锯齿?我试过用SceneAntialiasing。残废了,没用。我找不到其他方法来关闭它。

  • 问题内容: 对于PIL中的线条和椭圆,图像是粗糙的。 我发现仅在调整大小和缩略图中使用了抗锯齿功能。 绘制直线或椭圆形时,有什么方法可以进行抗锯齿吗? 问题答案: 本地执行此操作的唯一方法是使用超级采样。以所需大小的倍数渲染图像,然后使用进行渲染。

  • 我在我的项目中使用了InkCanvas,我注意到每当我画东西时,笔划都非常尖锐,一旦我松开鼠标按钮,它就会变得模糊。 有没有什么方法可以使笔划与绘制时的样子保持一致? 现在,我正在检查从图像中获得的阵列,并删除任何与颜色不完全匹配的像素。红色(即ARGB:255255,0,0)。。。我相信有一种更聪明的方法可以做到这一点! 提前谢谢。

  • 问题内容: 我们如何在CSS中应用类似于Photoshop的字体抗锯齿功能,例如清晰,锐利,强壮,平滑? 所有浏览器都支持这些吗? 问题答案: 主席先生,你在这里:-) 1个 2

  • 问题内容: 我使用旋转元素,-webkit-transform: rotate()而在Chrome14.0.835.2dev-m中,它对元素内部的文本确实做了一些奇怪的事情。它使我想起了使用“平滑”抗锯齿而不是“清晰”旋转文本时在Photoshop中获得的类似效果。 有人知道这是怎么回事吗?它特定于此Webkit或Chrome版本,还是可以解决此问题?(这也不是消除列表元素之间边界的锯齿) Her