Python 如何使用pyglet中的原始像素数据更改图像大小
在将图像加载到精灵之前,我需要能够更改图像的宽度或高度。我目前正在使用numpy获取中间的行或列,并继续将其插入图像中,直到其大小正确为止。我不知道这段代码是否有效,因为我在将原始图像加载回sprite并显示它时遇到了问题Python 如何使用pyglet中的原始像素数据更改图像大小,python,opengl,pyglet,Python,Opengl,Pyglet,在将图像加载到精灵之前,我需要能够更改图像的宽度或高度。我目前正在使用numpy获取中间的行或列,并继续将其插入图像中,直到其大小正确为止。我不知道这段代码是否有效,因为我在将原始图像加载回sprite并显示它时遇到了问题 def set_image_size(img, x, y): raw_img = img.get_image_data() format = 'RGBA' pitch = raw_img.width * len(format) rgba = n
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
原版雪碧:
使用sprite.scale拉伸:
对于这个精灵来说,这并不是一个很大的问题,因为我可以使用OpenGL四边形来绘制它,但我需要开始使用更复杂的精灵,这些精灵需要以上述方式进行缩放。所以问题在于您最初使用的图像分辨率的缩放,即16px宽和7px高。默认情况下,放大图像并不能以您期望的方式巧妙地填充空白 为了解决这个问题,您可以告诉OpenGL,放大图像中的每个新像素都应该从它的邻居那里获得灵感。通过在每次渲染精灵时向渲染循环中添加以下内容来实现此目的:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
重要的是,在每次渲染需要添加过滤器的精灵之前,都会调用该函数。不确定技术术语是什么,但必须在每个渲染序列中设置它,因为下次循环渲染函数时,它会被重置。这有一个花哨的词,我敢肯定
下面是一个工作示例:
从pyglet进口*
从pyglet.gl导入*
key=pyglet.window.key
类mainpyglet.window.window:
定义初始自我,宽度=800,高度=600,fps=False,*args,**kwargs:
超人,自我。初始宽度,高度,*args,**kwargs
self.x,self.y=0,0
glEnableGL_纹理_2D严格来说是不需要的,我认为这是默认设置,或者不会以任何显著方式影响此测试图像。
self.keys={}
self.mouse_x=0
self.mouse_y=0
图像本身最初是800x400
定位在x=0和y=50时,将其放置在底部
self.sprite=pyglet.sprite.Spritepyglet.image.load'test.png',50,50,batch=None
self.sprite.scale=20缩放高度,而不是宽度
self.alive=1
def on_draw self:
自我渲染
关闭自身上的def:
self.alive=0
鼠标上的def运动自身,x,y,dx,dy:
self.mouse_x=x
def on_键_释放自我、符号、修改器:
尝试:
del self.keys[符号]
除:
通过
def on_键按自身、符号、修改器:
如果符号==key.ESCAPE:[ESC]
self.alive=0
self.keys[符号]=真
def renderself:
自清
GLTEX参数化GLU纹理2D,GLU纹理MAG过滤器,GLU最近
GLTEX参数化GLU纹理2D,GLU纹理MIN过滤器,GLU最近
自我精灵
自我翻转
def runself:
当self.alive==1时:
自我渲染
------>这是一个关键问题,为什么你需要在加载到精灵之前更改它?当它是一个东西时?@Torxed。我需要这样改变它,因为当我使用缩放时,我的精灵会伸展。我不知道是否有办法避免这种情况,但我的游戏中的精灵需要以几乎任何宽度或高度渲染,而不需要将边缘舍入。我测试的一个精灵的比例几乎是一个长方形,我需要它使宽度变长,但它变成了一个椭圆形。比例应该尊重纵横比,所以可能有问题。你能截图一个例子并发布相关代码吗?@Torxed。谢谢你的建议,但我还是会收到奇怪的缩放效果。如果有帮助的话,我正在尝试重新创建一个在构造2中制作的游戏,其中缩放似乎是这样工作的。我添加了上面的例子。所以奇怪的是,你可能在视口中的某个点关闭了抗锯齿?使用类似的图像运行一个niminal工作示例:我无法重现此问题。所以有些地方你可能忘了做pyglet.gl.Configsample\u buffers=1,samples=4或?谢谢!这工作得更好,我不再有弯曲的边缘。然而,我认为平铺内部行/列是必要的原因之一是矩形的边界在边上被拉伸,因为我需要在纵横比不同的地方使用非均匀缩放。但是如果没有好的方法来改变像素数据,那么这个解决方案可能会很好地工作。遗憾的是,据我所知,没有一个。如果它是SVG或任何其他类型的向量,那么很容易实现您所需要的。但对于纯RGBA数据,除非有人花了一生的时间专门编写代码来解决这个难题,否则您所需要的几乎是不可能的。顺便说一句,我使用了精灵图像和GL_三角形的混合来实现你想要的。另外,屏蔽层过滤掉不需要的伪影是另一个丑陋的黑客。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)