如何使用pyglet中的原始像素数据来更改图像大小

问题描述 投票:0回答:1

在将图像加载到精灵中之前,我必须能够更改图像的宽度或高度。我目前正在使用numpy来获取中心行或中心列,并不断将其重新插入图像,直到其大小正确为止。我不知道此代码是否还能正常工作,因为我也一直无法将raw_image加载回sprite并显示它。

def set_image_size(img, x, y):
    raw_img = img.get_image_data()
    format = 'RGBA'
    pitch = raw_img.width * len(format)
    rgba = np.array(list(img.get_image_data().get_data(format, pitch))).reshape(-1, raw_img.width, len(format))

    mid_y = rgba[round(raw_img.height/2),:] # This is needed to stretch along Y
    while rgba.shape[0] < y:
        rgba = np.insert(rgba, round(raw_img.height/2), mid_y, 0)
    mid_x = rgba[:,round(raw_img.width/2)] # This is needed to stretch along X
    while rgba.shape[1] < x:
        rgba = np.insert(rgba, round(raw_img.width/2), mid_x, 1)

    raw_img.set_data(format, pitch, ''.join(map(chr, rgba.tostring())))

    return raw_img

[当我尝试将其涂抹到抽象图像上并将其涂抹到屏幕上时,我得到了怪异的红色条纹图像。我不需要太担心质量,我只想仅“拉伸/平铺”图像的内部,以免边缘变形。另外,我的图像很小,只有15 x 15像素左右。

我该如何解决这两个问题?

编辑:

当我使用sprite.scale时,它以奇怪的方式被拉伸:

self.sprite = pyglet.sprite.Sprite(self.image, self.x, self.y, batch=batch)
self.sprite.scale_x = self.width / 16

原始雪碧:Original Sprite

拉伸(带有sprite.scale):

enter image description here

对于此Sprite来说,这并不是什么大问题,因为我可以使用OpenGL Quads进行绘制,但是我需要开始使用需要以上述方式缩放的更复杂的Sprite。

python opengl pyglet
1个回答
0
投票
要解决这个问题,您可以告诉OpenGL,放大图像中的每个新像素都应从其邻居那里获得“灵感”。您可以这样做:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

在您的渲染循环中,重要的是在每次需要渲染滤镜的精灵的每次渲染之前都要调用此方法。不知道这是什么技术术语,但是必须重置每个渲染序列,因为它会重置。

这是一个工作示例:

from pyglet import * from pyglet.gl import * key = pyglet.window.key class main(pyglet.window.Window): def __init__ (self, width=800, height=600, fps=False, *args, **kwargs): super(main, self).__init__(width, height, *args, **kwargs) self.x, self.y = 0, 0 glEnable(GL_TEXTURE_2D) # Strictly speaking not needed, I think this is default or won't affect this test image in any significant way. self.keys = {} self.mouse_x = 0 self.mouse_y = 0 # The image itself is 800x400 originally # Positioned at x=0 and y=50 will place it at the bottom essentially self.sprite = pyglet.sprite.Sprite(pyglet.image.load('test.png'), 50, 50, batch=None) self.sprite.scale = 20 # Scale the height, not the width self.alive = 1 def on_draw(self): self.render() def on_close(self): self.alive = 0 def on_mouse_motion(self, x, y, dx, dy): self.mouse_x = x def on_key_release(self, symbol, modifiers): try: del self.keys[symbol] except: pass def on_key_press(self, symbol, modifiers): if symbol == key.ESCAPE: # [ESC] self.alive = 0 self.keys[symbol] = True def render(self): self.clear() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) self.sprite.draw() self.flip() def run(self): while self.alive == 1: self.render() # -----------> This is key <---------- # This is what replaces pyglet.app.run() # but is required for the GUI to not freeze # event = self.dispatch_events() if __name__ == '__main__': x = main() x.run()

这是您可以使用的测试图像:enter image description here

这是结果:

enter image description here
© www.soinside.com 2019 - 2024. All rights reserved.