Changing the Color of a picture [C#]

Shaitan00

Well-known member
Joined
Aug 11, 2003
Messages
343
Location
Hell
Fun question, I have an IMAGE (that I get from a bitmap file), it can be of pretty much anything (a character, an item, a weapon, a wall or floor, etc...) and depending on a value (level) I have to change its color.
For example let us use the WEAPON->BOMB picture - a simple bomp.bmp file with a white background and a black filled circle in the middle representing a bomb...

This is how I currently use it ...
Code:
Bitmap imgCell = (Bitmap)Image.FromFile("bomb.bmp");
imgCell.MakeTransparent();

What I want to do is change the COLOR of the bomb from BLACK to something else depending on the variable (level), so if level=0 then leave it as is, if level=1 then make the bomb BLUE, if level=2 make the bomb RED, etc...
Thing is I have no clue how to change the color of the picture (without affecting the actual original file itself)... I have no idea how to fill the bomb with a certain color?

Also, that is but the simplest example - I also have CHARACTERS (same idea) but for them I only want to change the color of the BODY, so same idea a level=0 gets the default body, a level=1 gets a BLUE body, etc...
And the only thing I want to change is the BODY of the character, not the hair, etc... How do you pinpoint that area only and change it from color X to color Y?

Any ideas, hints, and help would be greatly appreciated, thanks
 
This isnt going to be particularly easy to achieve. If the areas you wish to change on all files were a specific colour, then you could just check for pixels of that colour and then change the colour. Its seems from your example however that this wont be possible. Im assuming that whilst the bomb is black and you wish to change its colour, the character wont be black to start with. One way of doing it would possibly be to create a mask file. Basically a second image that contains only 2 colours, one colour represents which pixels of the original to keep, the other represents which to alter.

Im no expert at picture manipulation, but thats probably how Id go about it. Somebody more used to this kind of task may have a better idea.
 
Hummm.... you raise a good idea ... If I can ensure that the ONLY part of the picture of a color X needed to be changed (so have the characters body be GREEN and no other part) then is there a way to find the green pixels and change them to another color Y? (can you provide an example, I have no clue how that works)

But wouldnt that be greatly inefficient? Scanning through the entire picture pixel by pixel and changing only a specific section? I guess I would need narrow down the range manually ... is there no way to "fill this with color Y" as you do in Microsoft Paint?
 
It wont be greatly in-efficient because you wont do it every time you need to draw the image. You only need to do it when your game loads. The altered image can then be stored for use within the game. Using GetPixel and SetPixel would be one way of going about it, Im not sure it would be the most efficient however. Btw is it a bomberman clone your working on?
 
Can you give me an example of how to use SetPixel and GetPixel to
- Cycle through all the pixels of my image
- Determine what color it is
- Change the color if necessary

And yes it is a BomberMan-Style game - how did you guess :)
 
GetPixel/SetPixel can be bad news. They are VERY slow. There are some other not so easy solutions.

The first is to use paletted bitmaps, which actually allows you to go ahead and edit the palette. In other words, you can say "make everything thats blue change to green" by modifying a single palette entry, and it will happen like magic. Thats assuming you have software that supports creating and editing paletted bitmaps. Photoshop can do this. The problem is that GDI+ renders paletted bitmaps somewhat slowly (but still a speed boost over changing colors with GetPixel/SetPixel), so if speed is critical, the only viable solution here would be to write your own blitting code (Ive done it, and its a pain). The advantage to paletted bitmaps is that you can have multiple palette entries that are the same color (you can have a guy with a red hat and a red shirt, and by using different palette entries you can change the color of the hat without changing the color of the shirt).

Another solution would be to lock the bitmap and use pointers or Marshal functions to get at the data, and write your own color-changing code similar to the code you would write with GetPixel/SetPixel. (I will be posting a tutorial on this topic in the "Tutors Corner" forum today or tomorrow.)


Also, realize that if you are making a very simple game where you wont be doing too much palette style operations, GetPixel/SetPixel may be a viable solution.
 
marble_eater: I am very interested in your idea of using Color Palettes to perform the color changes - however I was under the impression that had to change ALL of color X to color Y - I am very interested in hearing more about how you would accomplish something like you described (red hat, red shirt).


But first off I have to get this code to work, this is what I have so far:
Code:
ColorPalette palette = imgCell.Palette;
palette.Entries[0] = Color.Black;
imgCell.Palette = palette;

However it isnt working, my "palette" is of entries lenght of 0 ... Looks empty...
I was wondering, could it be because my Bitmap (.bmp) isnt indexed (I was reading up on that)? If so how do you "index" a bitmap? (I am at a loss).
 
Which fill functions? There is no floodfill.

As far as how to change palette entries, yes it has to be indexed. That means you need software that can save indexed bitmaps. If you have Photoshop, take the final image, go to the Image/Mode menu and select Indexed. It provides some options for automatic palette creation. After you do this, save it as a Bitmap (or GIF or any paletted format, GIF will support transparency). Go to Image/Mode/Color Table and you can view the palette. Look for the color you want to change. The hex code for that colors index is the y coordinate then the x coordinate (fifth row down and third column over would be 0x42).

The code to modify a palette is as follows:
C#:
ColorPalette palette = IMAGE.Palette;
Color[] entries = palette.Entries;
// Edit entries here
// i.e. entries[0] = Colors.Pink;
IMAGE.Palette = palette; // Palette must be assigned back for changes to take effect
 
Back
Top