为调色板图像分配不同的调色板索引 [英] Assigning different palette indices to a paletted image

查看:267
本文介绍了为调色板图像分配不同的调色板索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Python和Pygame编写游戏.为此,图形将采用NES等旧视频游戏机的风格.因此,这些图形由具有2位(4色)图像的单个tileet文件组成,我希望能够在加载这些图像时为这些图像分配任意的4色调色板.

I'm writing a game with Python and Pygame. For this, the graphics will be in the style of old video game consoles like the NES. Therefore, the graphics consist of a single tileset file with 2-bit (4-colour) images, and I want to be able to assign an arbitrary 4-colour palette to these images when loading them.

我想要做的是使用8位(256色)调色板模式,该调色板已分为64个子调色板,每个子调色板分别具有4种颜色.每次我从2位图形文件加载16x16瓦片时,我都希望为其分配这些虚拟4色调色板之一.因此,在原始图块集文件中,调色板索引将为0-3,因为它是2位索引文件.我想将这个文件中的图块加载到内存中,并使用一个函数来将调色板索引从0-3重新分配到我选择的任何调色板偏移量,以便在将其涂抹到屏幕上时以我选择的4色进行着色调色板-与NES硬件的工作原理非常相似.这有点毛茸茸的解释,所以也许这张照片让它更清晰了:

What I want to do is use an 8-bit (256-colour) palette mode, with a palette that I have divided into 64 sub-palettes of 4 colours each. Every time I load a 16x16 tile from the 2-bit graphics file, I want to assign one of these virtual 4-colour palettes to it. So, in the raw tile set file, the palette indices are going to be 0-3, because it is a 2-bit indexed file. I want to load tiles from this file into memory, and use a function to reassign the palette indices from 0-3 to whatever palette offset I choose, so that when I blit it to screen, it is coloured in my choice of 4-colour palette -- much like the NES hardware works. This gets a little hairy to explain, so maybe this picture makes it a little clearer:

我环顾了Pygame和PIL的手册,却发现没有任何东西能让我像这样操作调色板文件.还有其他需要研究的库吗?还是我没有看到更简单的解决方案?

I have looked around the manuals of Pygame and PIL and found nothing that lets me manipulate paletted files like this. Are there any other libs to look into, or is there a simpler solution I'm not seeing?

推荐答案

您可以使用pygame.Surface.set_palette_at()进行此操作.对于您的情况,对于64个图块,您有四种颜色,因此要为特定图块重新着色,可以使用:

You can do this with pygame.Surface.set_palette_at(). In your case, you have four colours for sixty-four blocks, so to recolour a specific block, you might use:

for n, newRGBA in enumerate(fourNewColours):  # where fourNewColours are the RGBA tuples you want to plop into the palette.
    GameSurface.set_palette_at(palette_offset + n, newRGBA)  # where palette_offset is the number of the first palette index you want to replace (adding n to increment your way through the new colours).

这是您替换四种颜色的单个块的方法.首先将每个调色板推入游戏表面可能会更加复杂,因为pygame似乎会近似 blit'd images的调色板,而不是直接替换目标表面的索引.更复杂,因为我不知道如何为具有重复索引RGBA值的像素重新着色. (例如,如果调色板14/2和调色板40/1均为(90,91,200,255).我不知道pygame是否会将所有具有该RGBA值的像素分配给调色板索引57(来自Pal14/2),对于Pal40/1,idx 160不设置任何值,或者两者是否保持不同. 如果您想即时给图像重新上色,这可能会成为一个问题.如果您选择稍长的路线并根据需要更改游戏调色板,然后稍后使用相关的新调色板对表面进行着色(或重新着色),则它应该能够可靠地工作.

This is how you might replace individual blocks of four colours. Pushing every palette into the game surface to start with may be more complicated, since pygame seems to approximate blit'd images' palettes instead of replacing the destination surface's indices directly. More complicated because I don't know how you'd go about recolouring pixels with duplicate index RGBA values. (For instance if Palette 14/2 and Palette 40/1 are both (90,91,200,255), for example. I don't know if pygame will assign all pixels with that RGBA value to palette index 57 (from Pal14/2) and none to idx 160 for Pal40/1, or if the two will remain distinct. This could become an issue if you want to recolour images on the fly. It ought to work reliably if you take the slightly longer route and alter the game palette as needed, then blit (or re-blit) surfaces with the relevant new palettes later.

希望是有用的(即使已经超过两年半了)!

Hope that's useful (even though it's well over two and a half years later)!

如果您想查看该答案的较长版本,请查看

If you want to see a longer-form version of this answer, check out this link.

这篇关于为调色板图像分配不同的调色板索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆