Working with pixels and palette
-
Hello, I'm trying to program a "clone" of civilization III, using only C# and GDI+ (kind of exercice to learn). I've manage to make a functional map and map editor, and I'm trying to animate the sprites. It works, except for two things : shadows and player color. My animation are 256 colors storyboard. I know that the last 20 indexes are used for shadows. Question 1: how can I know with C# and GDI+ what is the index in the palette of a pixel? The GetPixel function gives the color, not the index. Question 2 : How can I use an alphablending effect, but only on some indexes of the palette? Is it possible? Question 3 : for player color, how can I replace the 10th index color in the palette by another color? Supposing player color is the 10th index of course. Thanks
-
Hello, I'm trying to program a "clone" of civilization III, using only C# and GDI+ (kind of exercice to learn). I've manage to make a functional map and map editor, and I'm trying to animate the sprites. It works, except for two things : shadows and player color. My animation are 256 colors storyboard. I know that the last 20 indexes are used for shadows. Question 1: how can I know with C# and GDI+ what is the index in the palette of a pixel? The GetPixel function gives the color, not the index. Question 2 : How can I use an alphablending effect, but only on some indexes of the palette? Is it possible? Question 3 : for player color, how can I replace the 10th index color in the palette by another color? Supposing player color is the 10th index of course. Thanks
If you want alpha blending, you'll need to use 32-bit color where the high 8 bits is the alpha channel. These are per-pixel. If you want to get the palette index for a color, first get the
Color
as you're doing. Then you'll need iterate through theColorPalette
.Entries for theImage.Palette
:Color pixel = bmp.GetPixel(0, 0);
ColorPalette palette = bmp.Palette;
for (int i=0; i<palette.Entries.Length; i++)
if (palette.Entries[i].Equals(pixel)) return i;
return -1;Microsoft MVP, Visual C# My Articles
-
If you want alpha blending, you'll need to use 32-bit color where the high 8 bits is the alpha channel. These are per-pixel. If you want to get the palette index for a color, first get the
Color
as you're doing. Then you'll need iterate through theColorPalette
.Entries for theImage.Palette
:Color pixel = bmp.GetPixel(0, 0);
ColorPalette palette = bmp.Palette;
for (int i=0; i<palette.Entries.Length; i++)
if (palette.Entries[i].Equals(pixel)) return i;
return -1;Microsoft MVP, Visual C# My Articles
Thanks for the answer, but it won't work. I know that in the palette the last index is the transparency color, whatever the actual color. It is usually magenta, but it could be something else. And if it is Magenta, but the first color is also magenta, then only some pixels (last index) must be transparent, the other one (first index) must remain magenta. That's why I'd like to get the actual index, and not only the color
-
If you want alpha blending, you'll need to use 32-bit color where the high 8 bits is the alpha channel. These are per-pixel. If you want to get the palette index for a color, first get the
Color
as you're doing. Then you'll need iterate through theColorPalette
.Entries for theImage.Palette
:Color pixel = bmp.GetPixel(0, 0);
ColorPalette palette = bmp.Palette;
for (int i=0; i<palette.Entries.Length; i++)
if (palette.Entries[i].Equals(pixel)) return i;
return -1;Microsoft MVP, Visual C# My Articles
I've found a solution to one of my problem. Bitmap.Palette return a copy of the palette. So I need to do ColroPalette palette = bmp.Palette; palette.Entries[0] = Color.FromArgb(150,255,255,255); bmp.Palette = palette; And then it works, even for the alphablending, and the picture is 8bpp indexed, it doesn't need to the 32-bit color. However, your solution to get the index of a pixel will not work, as I can have several indexes in the palette with the same color, but they must be processed differently. For instance, the last index is the background color and must be 100% transparent. But if it is magenta, and the 76th index is also magenta, then only the background must become transparent, and the 76th inndex must remain magenta
-
I've found a solution to one of my problem. Bitmap.Palette return a copy of the palette. So I need to do ColroPalette palette = bmp.Palette; palette.Entries[0] = Color.FromArgb(150,255,255,255); bmp.Palette = palette; And then it works, even for the alphablending, and the picture is 8bpp indexed, it doesn't need to the 32-bit color. However, your solution to get the index of a pixel will not work, as I can have several indexes in the palette with the same color, but they must be processed differently. For instance, the last index is the background color and must be 100% transparent. But if it is magenta, and the 76th index is also magenta, then only the background must become transparent, and the 76th inndex must remain magenta
Sorry, but in most cases it will work. Palettes don't usually contain the same color more than once. Sure, I suppose they could - but it's atypical. All the graphics programs I've worked with - and quite a bit - like Photoshop (last 4 versions), GiMP, and a handful of lesser-known programs consolidate the palette for space and because it's usually pointless to have more of the same color in a palette. So, just because it doesn't work for your atypical example, don't say it doesn't work.
Microsoft MVP, Visual C# My Articles
-
Sorry, but in most cases it will work. Palettes don't usually contain the same color more than once. Sure, I suppose they could - but it's atypical. All the graphics programs I've worked with - and quite a bit - like Photoshop (last 4 versions), GiMP, and a handful of lesser-known programs consolidate the palette for space and because it's usually pointless to have more of the same color in a palette. So, just because it doesn't work for your atypical example, don't say it doesn't work.
Microsoft MVP, Visual C# My Articles
Sorry if I was a bit offensive. Your solution works, but not in my particular case, because it is quite likely that the palette contains several identical colors, and there should be used as different color by the software.