[Solved] Coloring a gray image

Not quite sure if his belongs here but I want to color an image which consits of gray value which always come from a palette of 16 gray colors. No I want to to color my gray image with a specific color for every grav color in the palette.

I know how to color a single image with a color, but how do I do this when i want to color different for different gray values. Like this:

http://img15.imageshack.us/img15/9084/testgia.png

I guess I with a Shader? But if, how needs the shader to look like?

WRT Shaders. Think about the following questions. Does the memory requirement become too big if I prestore the various animation frames (most likely not) and/or am I going to need to transfer a crazy amount of data from CPU to GPU (again probably not) And finally: Do I want to play with shaders for the learning experience.

Create a new palette (or explicit RGB images) by treating the grayscale value as luminance and use a “uniform color space” transform the create the new image. So, if you have a target color in RGB, you convert that RGB value to some uniform colorspace. Then for each pixel you set the luminance value to the grayscale value. You take that and convert back to RGB. Some examples include: YCbCr and YUV.

Okay, do be honest. I kinda don’t understand a word :smiley: I should probalty get more expierence before doing stuff like that :slight_smile: So for the current project I will take the normal color bin (game needs to be done in 3 months :emo:)

Make a copy of the gray scale image, get the pixels from the image, take one color component (red for example) and use that value as index to look up the color in the new color palette (essentially being an array of 256 colors, if you use 8 bit per color channel). Write the new color back to the pixel and you are done.

Oh and how do i set this to the new image ? I’m using Slick2D btw so I’m a total noob (and college is sucking time like a hell >:() (I learn best when seeing some example code, but I know that this is much to ask :()

Never used slick, but according to the javadoc, you would do it by creating an ImageBuffer of the size of your Image and use a nested for loop to get the colors at all [x;y] coordinates. Then set the colored pixel using ImageBuffer.setRGBA(). In the end call ImageBuffer.getImage() to get the new colored image.

http://slick.cokeandcode.com/javadoc/org/newdawn/slick/Image.html
http://slick.cokeandcode.com/javadoc/org/newdawn/slick/ImageBuffer.html

Ah so this is not “to heavy” ? :slight_smile: Seems like one of that KISS stuff. I will try it, thanks a lot!

Writing out a new image is certainly “heavy” in that you’re not going to want to do it inside your render loop. The fast way to do it would be with a fragment shader you supply a “tint” value to.


uniform vec4 tint;
void main() {
    gl_fragColor += tint;
}

If you only want to tint the grey parts, then it’s a simple matter to test whether r, g, and b are equal:


uniform vec4 tint;
void main() {
    if (gl_fragColor.rg == gl_fragColor.gb)  
       gl_fragColor += tint;
}

Yes, it should be done beforehand. Just create as many different Images as you need before starting the game.

I think the OP doesn’t want to tint, but replace grayscales with arbitrary colors.

My suggested solution and cylabs are nearly identical. The difference is that cylab’s operates in RGB space and mine in a uniform. The difference between the two will not typically be huge. So I’d go with cylab’s easier one unless the differences are judged to be noticeable and worth addressing. The way to tell would be to create two sets of images, one blue and one green and decide if the perceived brightness between the two is worth addressing.

I want to do this at runtime, so I would have to load a lot of images because currently I just interpolate between pure white and my set color to get a color. But the ability to determine which gray color should be tinted would be great! But it seems I lack expirence in Shader so I will have to implement it with just tinting the whole image :slight_smile: Maybe I have some time in the end of this semester to change that.

Edit:
I’m not even good at Shaders. I simply had no time to learn them (holiday issue: You plan to do something, but in the end you’r not doing ist :()

I’ve just learned shaders myself – this one just happens to be a really simple shader. I suspect whether you want to use a shader depends on what circumstances you want to tint your model: if you want to do the RPG tropes of turning an existing sprite blue because it’s frozen, or green for poisoned, a shader might really be a good option. If you’re doing the Diablo route of using a different color of the same sprite for different monsters, you may as well just pre-generate them.

Nope thing is, I want the game to get “grayer” the further you get in the game (This has something to do with the story and stuff). So i guess Shaders are really cool here :smiley:

Yah a shader would be the appropriate way to do it. As Roquen mentioned, you probably don’t want to uniformly scale down the R,G, and B components, or you’ll end up with red and blue sort of muddling into each other with green still visible. Might be a bit matrixy, having an overall green tint, but not likely what you want. Basically you want to bias the colors using the NTSC values before you scale them for brightness. Little google-fu turned this up: http://www.eng.utah.edu/~cs5610/lectures/GLSL-ATI-Intro.pdf – the very second example has a grayscale shader in it.

Okay this all sounds pretty new to me, so I guess I can’t sit around and wait for magic to make it work :slight_smile: Are there any decent Shader Tutorials? (beside the pdf I’m reading right know :D)

Since the amount of colors seems very limited, a simple handcrafted lookup texture should be enough.

Oh didn’t I mentioned that the interpolation could nearly take every value between 0.0 and 1.0 ? And that this need to apply to all textures in game expecpt the menu :slight_smile:

I will see if I can do this if I understand the difference between a vertex and a fragment Shader :smiley:

when you can normalize these 16 grayscale colors to values between 0 and 15, you can make 4096 palettes with one 256x256 texture. Let’s say you provide one grayscale and one color palette per gfx asset. This means you can support 2048 16 color assets with one texture. All you have to do is to provide two palette indices, one blending factor and the palette texture istelf to the fragment shader. Then you can blend between two palettes… This would be useful if you need multiple palettes for the same asset. If this isn’t nescessary, the fastest way with the highest amount of flexibility for the artist would be to just provide two textures - one with colors one without - then you can blend between both textures with a blend factor. If you just want to desaturate everything (provide a color image and make it grayscale) a simple desaturation color transform that is scaled by a blend factor would be enough (formula for luma/grayscale: Y=0.3r+0.59g+0.11*b, also see what Roquen wrote).

This sounds pretty cool and I even think to understand it a bit (not what rouqen said, might be because I’m german and not the best in english or something :'D). Still need to work out how Shaders work :slight_smile:

Oh and I want to make a grayscale image get some color :slight_smile:

You may need to start here: http://slick.javaunlimited.net/viewtopic.php?t=3212