Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » Color Replacement in sprites, easy way to do it ?

This thread is locked; no one can reply to it. rss feed Print
Color Replacement in sprites, easy way to do it ?
Marco Antônio Linhares
Member #3,655
June 2003
avatar

I'm having some trouble in repainting my sprites, and since I didn't find any topic about it, I think it could be a good discussion.

Every time I have to resize a picture that has a pink background (255, 0, 255) or any other color, the border colors get messed up after I resize and I have to repaint the borders back to pink before using them again!

If I don't do this, the draw_sprite function in allegro will show the picture borders and the effect is not so nice.

For example, I have these sprites:

{"name":"598953","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/6\/76fae2a1677e62e15b3a44cd401b48f2.jpg","w":810,"h":724,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/6\/76fae2a1677e62e15b3a44cd401b48f2"}598953

that get displayed like this:

{"name":"598952","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/d\/edf10c498d98cc95b35d94fe8749de3b.jpg","w":586,"h":460,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/d\/edf10c498d98cc95b35d94fe8749de3b"}598952

But, after I resize the sprites they become:

{"name":"598950","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/c\/1cda2d0dc68e5ec0d469eceb0e0f6237.jpg","w":390,"h":354,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/c\/1cda2d0dc68e5ec0d469eceb0e0f6237"}598950

and get displayed like:

{"name":"598951","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/9\/598bce2b7fbdd9872f89dab93c2b0f90.jpg","w":424,"h":304,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/9\/598bce2b7fbdd9872f89dab93c2b0f90"}598951

Repaiting the borders to make them look lice again has been a tedious work since both Photoshop and Gimp doesn't have an easy way to do this. In Gimp you have to go to the Exchange Colors option each time for each different color and in Photoshop when you select a pixel, it doesn't exchange to the color you want or it repaints a region of pixels to another color different from (255,0,255), although you select this as the result color.

Any ideas or software suggestions that can make this task easy ? Right now, going frame by frame has been the fastest way so far! Too bad! It would be great if there was a program that I could click once for each pixel and it would exchange the color right away!

Marco Antônio

Arthur Kalliokoski
Second in Command
February 2005
avatar

I didn't see a quick and easy answer in these threads, but check them out yourself

http://www.google.com/#hl=en&q=%22magic+pink%22+sprite+blend+site%3Aallegro.cc&aq=f&oq=&aqi=&fp=aazfVjAAjGM

They all watch too much MSNBC... they get ideas.

Kibiz0r
Member #6,203
September 2005
avatar

Keep your sprites on a different layer than your mask color and don't use anti-aliasing.

LennyLen
Member #5,313
December 2004
avatar

It would be great if there was a program that I could click once for each pixel and it would exchange the color right away!

How about one which goes though every .bmp file in a directory and converts every almost-magic-pink pixel to magic-pink? It's not perfect, but it should save you some time. With the image you provided, I found giving it a tolerance value of 100 converted most of the effected pixels, without converting any of your asteroid.

#SelectExpand
1#include <allegro.h> 2#include <stdio.h> 3#include <stdlib.h> 4 5 6int convert(const char *filename, int attrib, void *param); 7 8 9int main(int argc, char *argv[]) { 10 11 int tolerance; 12 13 if (argc < 2) { 14 allegro_message("Error: You need to provide a tolerance value\n"); 15 exit(-1); 16 } 17 18 19 tolerance = atoi(argv[1]); 20 if (tolerance <= 0) { 21 allegro_message("Error: Tolerance was negative, or not a number!\n"); 22 exit(-2); 23 } 24 25 allegro_init(); 26 set_color_depth(32); 27 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 0, 0, 0, 0); 28 29 for_each_file_ex("*.bmp" , 0, 0, convert, tolerance); 30 31 return 0; 32 33} 34END_OF_MAIN() 35 36 37int convert(const char *filename, int attrib, void *param) { 38 39 BITMAP *bmp; 40 int y, x, c, r, g, b, magic_pink = makecol(255, 0, 255); 41 int tol = (int)param; 42 43 bmp = load_bitmap(filename, NULL); 44 if(!bmp) { 45 46 allegro_message("Error loading \"%s\"", filename); 47 return -1; 48 49 } 50 51 for (y = 0; y < bmp->h; y++) { 52 53 for (x = 0; x < bmp->w; x++) { 54 55 c = getpixel(bmp, x, y); 56 r = getr(c); 57 g = getg(c); 58 b = getb(c); 59 60 if ((r > 255 - tol) && (g < tol) && (b > 255 - tol)) 61 putpixel(bmp, x, y, magic_pink); 62 63 } 64 65 } 66 67 save_bitmap(filename, bmp, NULL); 68 69 return 0; 70 71}

Marco Antônio Linhares
Member #3,655
June 2003
avatar

Great suggestions, thanks!

One problem is that I can't always keep my sprite on different layers as I use BMP and also I get the pictures from sites all over the internet.

I was searching that link and someone mentioned the palette. If I could could change the pink-like colors on the palette to 255,0,255 I could solve the problem.

598958

Is there a way to edit the palette ? I exported it from grabber and got only a bmp written pal!

598959

PS:I just saw your code Lenny. I'll try that. Thanks!!

Marco Antônio

LennyLen
Member #5,313
December 2004
avatar

PS:I just saw your code Lenny. I'll try that. Thanks!!

Good luck with it! I'm pretty sure it won't blow anything up. ;)

I forgot to say, make a copy of the bitmaps before you run it, as it will overwrite the originals (though you could easily modify the code to create new files).

Johan Halmén
Member #1,550
September 2001

I'd do something like:
1. read the BMP into Gimp
2. add transparency to the layer
3. make magic oink the transparent colour
4. resize the sprite
5. change transparent area to magic oink
6. save as BMP

I don't know out of memory if step 5 can be done as one step. If not, add the magic oink as an underlying layer, then save as BMP. All layer and transparency stuff happens in Gimp, which doesn't mind that the file is BMP. Not until you save it again, it complains about layers, transparency and BMP, but it will nicely merge everything into one layer without transparency.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Marco Antônio Linhares
Member #3,655
June 2003
avatar

That just happened! I changed the tolerance to 200 and lost all my original bmps!! I'm glad I made a backup before executing! hahah

I guess that's a magic function to make magic pink! Setting 150 tolerance gave me a pretty impressive result.

{"name":"598962","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/8\/e84eb1aa7fd58592e3f17c0ec86ff8ac.jpg","w":632,"h":440,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/8\/e84eb1aa7fd58592e3f17c0ec86ff8ac"}598962

For 160 tolerance I lost some pixels. Can you explain the logic behind this condition ?

if ((r > 255 - tol) && (g < tol) && (b > 255 - tol))
putpixel(bmp, x, y, magic_pink);

You can see in the picture that there are still some pixels that need to be replaced. I think for these pixels, we could set that for tolerances between 150 and 200 put black instead of leaving it the same color.

Thank you so much! :)

Marco Antônio

Neil Walker
Member #210
April 2000
avatar

Kibizor gave you the two answers.

1. In photoshop/gimp/etc there is an option to turn anti-alias on and off which will fix the problem.

2. Why can't you use layers? all you have to do is export them to bitmap when you are ready and you have the benefit of layers.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

weapon_S
Member #7,859
October 2006
avatar

Method in GIMP without layers:

  • Layer->add alpha channel

  • Magic-wand-select the pink

  • Delete

  • Select->select none

  • Scale

  • Layer->transparency->threshold alpha(127)

  • Layer->transparency->remove alpha channel(Make sure your background colour is magic pink)

Addition: Pink select for sprites with troublesome myriad of holes, but no colours resembling magic pink(uses layers)

  • Layer->transparency->colour to alpha(magic pink)

  • Layer->duplicate layer

  • @bottom layer:
    Layer->transparency->threshold alpha
    (Channels:) Turn of alpha channel editing (i.e. not alpha channel view)
    edit->fill with bg colour(magic pink)
    (Channels:) Turn on alpha channel editing (i.e. not alpha channel view)

  • @top layer:
    merge down

  • scale

  • threshold apha

  • remove alpha channel (magic pink as bg colour)

Marco Antônio Linhares
Member #3,655
June 2003
avatar

Great! I'll try each technique to see what works best and post the results later. I hope other members can benefit from this discussion! :)

Marco Antônio

Johan Halmén
Member #1,550
September 2001

:-X:-X Yes, my method totally fails. At least the thing with placing magic oink underneath.

I think the main problem is that a one bit transparency mask (like magic oink) should only be used with 8 bit depth, where you have 255 colours and one transparent "colour". If you want high colour sprites (24 bit), your transparency should use 8 bits (32 bits alltogether) to match the smoothness of the colours. Magic oink is something inbetween. You have high colour sprites, 16.7 M colours and one of these colours is your transparent colour.

Came to think of it, I have done what I tried to describe as the step 5 in my earlier post. But instead of painting the underlying layer with magic oink, I painted it with a solid colour as equal as possible the colour of the background in my game scene, where the sprite most likely would appear. Then I merged the two layers (still in Gimp), then I used the magic wand to mark the background. Here I could use a threshold near or equal to zero. Then I changed the marked background area to magic oink, ensuring that the marked area didn't have an antialiased edge.

If your asteroid sprite were to appear on a light blue sky, the sprite would now have a bluish glow around the edge, before the magic oink begins. It would look good when using draw_sprite() on the light blue background, but it would look terrible against a black deep skye. To be able to use same sprites on any background, the edge of the sprite must be very jagged, which only look somewhat good in 8 bit graphics. Either that or you should use 32 bit sprites with 8 bit alpha transparency.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Marco Antônio Linhares
Member #3,655
June 2003
avatar

I tested and everything works just fine! I guess now I have many solutions to the same problem. Instead of resizing, it is much easier to first delete the pink layer, resize and them put it back.

If I get an image that doesn't have a pink layer than it is better to turn anti-aliasing off and them resize.

I also discovered another way! In Photoshop go to Image -> Mode -> Color Table and you can see every colors that your picture has. In this menu it is much faster to exchange colors and you can change pink-like colors to magic pink easily!

Thanks for all the help! The people here really help new game developers! I'll credit everyone on my game when it is done! :)

Marco Antônio

Dario ff
Member #10,065
August 2008
avatar

If you would like to know, in Photoshop, when you turn Image > Modes > Indexed Mode on, It resizes pretty much like allegro does, and the borders stay well. Still, bitmaps look as ugly when software rendering resizes :P

TranslatorHack 2010, a human translation chain in a.cc.
My games: [GiftCraft] - [Blocky Rhythm[SH2011]] - [Elven Revolution] - [Dune Smasher!]

Audric
Member #907
January 2001

It's an old question, but worth an answer:

(About PALETTE entries in datafiles) Is there a way to edit the palette ? I exported it from grabber and got only a bmp written pal!

The grabber saves a dummy 256-color bitmap, that only contains the letters "PAL.", in monochrome text. But the full 256-color palette is present in the file!
It works the same when you need to put a palette in datafile : You read from any supported 256-color image format (bmp, pcx...), and only the palette will be extracted and stored.

Tobias Dammers
Member #2,604
August 2002
avatar

Here's why you are in trouble:
Magic pink is only magic to allegro, for most other things (including photoshop, GIMP, and what have you) it is a regular color (255, 0, 255). When resizing, photoshop and some other programs apply anti-aliasing, depending on the settings, which means that for each pixel, a weighted average of the corresponding pixels in the original image is used. When one or more of these pixels are magic pink, the resulting color will also be pink to some degree, but not fully. For example, if four pixels are in the mix, one of which is black, and the other three are pink, and all equally weighted (academic example, but easier to calculate) the resulting color will be (191, 0, 191). This still looks fairly pink, but it not the exact same color as 'magic' pink, so allegro doesn't treat it as magic. A difference of 1 in only one component is enough to turn magic pink into regular pink.
To solve the issue, you need to make sure whatever program is responsible for resizing treats the transparent pixels as transparent, not as pink. Alternatively, you can choose not to use anti-aliasing, in which case the whole problem disappears since no color interpolation will happen.

Here are some options you have to do this:
a) Save your images in a format that supports actual transparency or even alpha channels (e.g. gif, png, tga), and use alpha blending or a proper loading routine in allegro. You may have to jump through a few hoops to make it work in allegro, but it's probably worth the effort (especially considering the excellent compression rates you can get with png compared to grabber and bmp).
b) Use a background in a color that matches the average background color in your game (e.g. black for a space shooter, greenish brown for a top-down army shooter, etc.); after resizing, use a flood fill with zero tolerance to turn the background color into magic pink. If your art style is cartoon-ish (that is, with black outlines), use (0, 0, 0) for the outlines and something like (1, 1, 1) for the background.
c) Turn anti-aliasing off
d) Write a little tool that you can use to batch-resize your sprites, and which keeps transparency intact. If you intend to use paletted images, you can add color conversion to the same tool, and if you make it a command-line tool, you can even include it in your build process.
e) Put the background color into a separate layer, and edit the image in a layer that has one bit of alpha (if your image editor can handle this). Keep this version for further editing; then resize and merge down.

As a general note, it is a good idea to keep the original and resized versions in separate folders, so that the risk of overwriting the wrong one is smaller. Also, use some sort of backup mechanism - either manually zip the entire image folder every now and then, or use a version control package (e.g. subversion) so you can always revert to the last "good" situation. The same goes for code, obviously.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

agent_smith
Member #10,673
February 2009

I'm sure you have already found a solution to your problem but I wanted to let you know how to replace 1 color with another color. A 1:1 color replacement. Unfortunately Adobe's Color Replacement Tool is actually a Color Blending Tool since the results are blending two colors together and not replacing 1 color for another. I've been working with Adobe to find out why I cannot do a 1:1 color replacement but so far everything they suggested has failed. I asked on another forum called the photoshopforums.com and It took a few days but I was able to get a solution.

My alias is anakin666 here:
Photoshop 1:1 color replacement

Check out the link I posted a picture there of the problem. If the border that is changing is all the same altered pink color you can use Color Range and select it as well as any other pink variations and once you're satisfied you can hit Ctrl-U from the Color Range dialog box and all the altered pink pixels should now be selected. Once this happens you can use fill or use a paint brush with 100% hardness and paint as fast as you want because it'll ONLY paint inside the selected area even if you go outside the lines.

Onewing
Member #6,152
August 2005
avatar

Hey, I didn't read all the suggestions, but here are some of mine. I had a bit of trouble with this myself over the speedhack weekend.

In photoshop, if you go to preferences and set the interpolation method to nearest neighbor (under general settings), it shouldn't resize so ugly. However, this wasn't added until after version 3.0, which is what I have, so it didn't help me (nor did I get to test it obviously).

I got so sick of waisting my time during the competition, that I decided to write a hack to blend the magic pink pixels in. It's essentially LennyLen's idea, just blending (that is, reducing red and blue, increasing green by a proportionaly amount...) instead of replacing the offending pixels. It works okay, but the zooming feature lets everyone know my not-so-well-kept secret.

Another method is to do everything without the magic pink. This can be done in photoshop or paint (although better in photoshop). When your done with the graphics and have it to the size you want, make a layer behind the image and color it something that looks average to the colors you have in your graphics. For your rock picture, you could use a low-saturated brown. Then add a layer on top and paint the intended magic pink areas magic pink (with anti-aliasing turned off).

Lastly, you can make an anti-aliased image using TGA with this method. Those are the different methods I currently use depending on the situation...

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Wilson Saunders
Member #5,872
May 2005
avatar

How about you paintbucket all magic pink to black or some other more neutral background color. Do the resize, then paint bucket all the black back to magic pink. If you are using an advanced tool like GIMP or Photoshop be sure to set your tolerance to 0 or else it might paint over parts of the image you don't want to paint over. Also there may be some pixels you don't want to be black after the 2nd paint bucket, but those will stick out like a sore thumb. Use the pen (non anti aliasing tool) to recolor them pink.

________________________________________________
Play my games at http://monkeydev.com

Johan Halmén
Member #1,550
September 2001

I tested that on Gimp and the Paintbucket did some anti-alias kind of blending at the edges. Maybe that's avoidable with some settings. One would like to be able to use the Paintbucket with some threshold but without the soft edge/anti-aliasing thing.

Instead of directly using the Paintbucket, one can use the colour marker or wand with some threshold and without the soft edge. And after that Fill with FG color.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

agent_smith
Member #10,673
February 2009

@Wilson Saunders- Thanks for noting the tolerance I wish Adobe would have suggested that to me when I was having problems using the paint bucket and after filling the space it would blend anything bordering it. I put the tolerance at zero and it works. Thanks!:D

@Johan Halmén- I only get the soft edge blending when I alter the image. For example if I make a black border then fill the inside with pink and then resize the too much (causing the width of the border to be altered) then it will blend with the pink. Whether its resized too large or too small if the border's width changes its over :(

Johan Halmén
Member #1,550
September 2001

...then fill the inside with pink and then resize...

This is the exact point of error. You may not resize anything that has magic pink. It doesn't make any difference whether it's inside or outside. Any border between pink and any other colour (or any two colours) gets mixed when resized.

The very fundamental order is:
1. Remove pink
2. Resize
3. Put pink back

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Go to: