|
Replacing specific color range |
GullRaDriel
Member #3,861
September 2003
|
Take a look at the picture, all colors except hands are 'pure' colors. {"name":"591971","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/8\/b8d1678789bd504182193c7391f1b202.png","w":320,"h":240,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/8\/b8d1678789bd504182193c7391f1b202"} I need to replace each of these color by another one, but quickly. What is the way , faster than getpixel, that I can use ? Thanks "Code is like shit - it only smells if it is not yours" |
Johan Peitz
Member #9
April 2000
|
If you're using 8bit I would go for palette changes, but something tells me you are not... -- |
Johan Halmén
Member #1,550
September 2001
|
Use palettes. Or prerender, either using a graphic editor (great opportunity to discuss in this thread why Gimp sucks/is great) or during game setup. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest. |
CGamesPlay
Member #2,559
July 2002
|
Use palettes, prerender, or use OpenGL. [append] -- Ryan Patterson - <http://cgamesplay.com/> |
Onewing
Member #6,152
August 2005
|
Quote: Use palettes, prerender, or use OpenGL. Or use getpixel to build an array and then use the array to putpixel back the colors with a given offset to change your colors, as long as your image doesn't...change. ------------ |
ImLeftFooted
Member #3,935
October 2003
|
There are gradients there... Ya good luck. Easier to redo the art. |
Matt Weir
Member #7,476
July 2006
|
Gradients can be overcome by converting to HSL and not using the lightness but there will be problems if any of the gradients fades to pure black. The human brain is pretty good at putting imaginary boundries in images. As far as I can think, getpixel is the only way and it will be slow. I can think of a few ways to optimize but all sacrifice accuracy. +1 for finding another way. Matt. |
Johan Halmén
Member #1,550
September 2001
|
Solder a switch to your monitor cable, which switches the r, g and b channels. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest. |
GullRaDriel
Member #3,861
September 2003
|
I made some tests, and it is working (as expected) with getpixel/putpixel. I will perhaps try to use the "block data transfer" method. Here is the result, the colors are random and take the gradient : And here is the code : 1#include <allegro.h>
2
3BITMAP *in , *out , *buf;
4
5int x , y, it , c , cc, r, g , b , r1 , b1 , g1 , c1 , c2 , c3 , c4 , c5 ,c6,c7 ;
6
7int main( int argc , char *argv[] ){
8
9allegro_init();
10install_keyboard();
11install_mouse();
12
13
14set_color_depth( 32 );
15
16set_gfx_mode( GFX_DIRECTX_WIN , 320 , 240 , 0 , 0 );
17
18in = load_bitmap( "test.bmp" , NULL );
19
20out = create_bitmap( in -> w , in -> h );
21
22buf = create_bitmap( SCREEN_W , SCREEN_H );
23clear( buf );
24clear( out );
25
26 c1 = makecol( rand()%255 , rand()%255 , rand()%255 );
27 c2 = makecol( rand()%255 , rand()%255 , rand()%255 );
28 c3 = makecol( rand()%255 , rand()%255 , rand()%255 );
29 c4 = makecol( rand()%255 , rand()%255 , rand()%255 );
30 c5 = makecol( rand()%255 , rand()%255 , rand()%255 );
31 c6 = makecol( rand()%255 , rand()%255 , rand()%255 );
32 c7 = makecol( rand()%255 , rand()%255 , rand()%255 );
33
34 for( x = 0 ; x < in -> w ; x ++ )
35 {
36 for( y = 0 ; y < in -> h ; y ++ )
37 {
38 cc = -1;
39
40 c = getpixel( in , x , y );
41 r = getr( c );
42 g = getg( c );
43 b = getb( c );
44
45 if( r > 88 && b == 0 && g == 0 ) /* rouge tete */
46 cc = c1 ;
47 if( r > 88 && b > 0 && g == 0 ) /* roste cou */
48 cc = c2 ;
49 if( r == 0 && b > 0 && g > 0 ) /* bleu manche */
50 cc = c3 ;
51 if( r > 88 && g > 0 && b == 0) /* veste */
52 cc = c4 ;
53 if( b > 0 && r == 0 && g == 0 ) /*pantalon*/
54 cc = c5 ;
55 if( r > 88 && b > 0 && g > 0 ) /*mains*/
56 cc = c6 ;
57 if( r > 0 && r <= 88 && b == 0 && g == 0 )
58 cc = c7;
59 if( cc != -1 )
60 {
61
62 r1 = getr( cc );
63 g1 = getg( cc );
64 b1 = getb( cc );
65
66
67 if( r > 0 )
68 {
69 it = r;
70 }
71
72 if( g > 0 )
73 {
74 it = g ;
75 }
76
77 if( b > 0 )
78 {
79 it = b ;
80 }
81
82 r1 = (r1 * it)/255 ;
83 g1 = (g1 * it)/255 ;
84 b1 = (b1 * it)/255 ;
85
86 if( r1 < 0 ) r1 = 0;
87 if( g1 < 0 ) g1 = 0;
88 if( b1 < 0 ) b1 = 0;
89 if( r1 > 255 ) r1 = 255;
90 if( g1 > 255 ) g1 = 255;
91 if( b1 > 255 ) b1 = 255;
92
93 putpixel( out , x , y , makecol( r1 , g1 , b1 ) );
94 }
95 }
96 }
97do{
98
99if( key[KEY_SPACE] )
100{
101 clear( out );
102
103 c1 = makecol( rand()%255 , rand()%255 , rand()%255 );
104 c2 = makecol( rand()%255 , rand()%255 , rand()%255 );
105 c3 = makecol( rand()%255 , rand()%255 , rand()%255 );
106 c4 = makecol( rand()%255 , rand()%255 , rand()%255 );
107 c5 = makecol( rand()%255 , rand()%255 , rand()%255 );
108 c6 = makecol( rand()%255 , rand()%255 , rand()%255 );
109 c7 = makecol( rand()%255 , rand()%255 , rand()%255 );
110
111 for( x = 0 ; x < in -> w ; x ++ )
112 {
113 for( y = 0 ; y < in -> h ; y ++ )
114 {
115 cc = -1;
116
117 c = getpixel( in , x , y );
118 r = getr( c );
119 g = getg( c );
120 b = getb( c );
121
122 if( r > 88 && b == 0 && g == 0 ) /* rouge tete */
123 cc = c1 ;
124 if( r > 88 && b > 0 && g == 0 ) /* roste cou */
125 cc = c2 ;
126 if( r == 0 && b > 0 && g > 0 ) /* bleu manche */
127 cc = c3 ;
128 if( r > 88 && g > 0 && b == 0) /* veste */
129 cc = c4 ;
130 if( b > 0 && r == 0 && g == 0 ) /*pantalon*/
131 cc = c5 ;
132 if( r > 88 && b > 0 && g > 0 ) /*mains*/
133 cc = c6 ;
134 if( r > 0 && r <= 88 && b == 0 && g == 0 )
135 cc = c7;
136 if( cc != -1 )
137 {
138
139 r1 = getr( cc );
140 g1 = getg( cc );
141 b1 = getb( cc );
142
143
144 if( r > 0 )
145 {
146 it = r;
147 }
148
149 if( g > 0 )
150 {
151 it = g ;
152 }
153
154 if( b > 0 )
155 {
156 it = b ;
157 }
158
159 r1 = (r1 * it)/255 ;
160 g1 = (g1 * it)/255 ;
161 b1 = (b1 * it)/255 ;
162
163 if( r1 < 0 ) r1 = 0;
164 if( g1 < 0 ) g1 = 0;
165 if( b1 < 0 ) b1 = 0;
166 if( r1 > 255 ) r1 = 255;
167 if( g1 > 255 ) g1 = 255;
168 if( b1 > 255 ) b1 = 255;
169
170 putpixel( out , x , y , makecol( r1 , g1 , b1 ) );
171 }
172 }
173 }
174}
175
176stretch_blit( out , buf , 0 , 0 , out -> w , out -> h , 0 , 0 , buf -> w , buf -> h );
177
178blit( buf , screen , 0 , 0 , 0 , 0 , buf->w , buf->h );
179
180}while( !key[KEY_ESC ] );
181
182allegro_exit();
183
184}END_OF_MAIN()
"Code is like shit - it only smells if it is not yours" |
miran
Member #2,407
June 2002
|
I only skimmed over the code but I didn't see any rgb2hsv and vice versa conversions so I'm guessing you're not doing it right. What you want to do is this: For each pixel: 1. Read colour (RGB format) -- |
GullRaDriel
Member #3,861
September 2003
|
Thanks for your help, but there is no need for me to use any other conversion than makecol and getX :-) The color value of the input picture is here for two reason: having the form to fill with a color, and picking the value as a percentage from 0 to 255. The whole thing is working as expected, it just need some king of optimisation as it will cause some load time. Here is the new version, where default replacement color is on screen for us to verify that it is using it correctly. Before: After: Executable + source (Win32) ( 7z archive ) I am waiting for give the cookies. Please post me the answer ;-) huhuhu "Code is like shit - it only smells if it is not yours" |
Indeterminatus
Member #737
November 2000
|
As requested, a post so you can hand out cookies. _______________________________ |
GullRaDriel
Member #3,861
September 2003
|
;-p "Code is like shit - it only smells if it is not yours" |
Matt Weir
Member #7,476
July 2006
|
Your pictures look like they contain a large ammount of dead space. If your checking every pixel in the large space perhaps you could divide and conquer. Only check every nth pixel (in both dimensions) if the nth pixel is one that needs to be changed then go back n/2 and check that pixel (and so on). You value for n would have to be one where you won't missed anything important so if your working on a picture with skinny lines it won't help but even at n=2 you'll save a lot of time. Basically trading precision for speed. Matt. |
Andrei Ellman
Member #3,434
April 2003
|
Quote: What is the way , faster than getpixel, that I can use ?
_getpixel Quote: r1 = (r1 * it)/255 ; If you don't mind the result being in the range 0-254 instead of 0-255, you can divide by using a shift. The code would then become.r1 = (r1 * it)>>8;. While not as accurate as the /255 method, it will be a lot faster. Also, you might want to consider using 8-bit graphics and using colour-map tables and draw_lit_sprite(). AE. -- |
GullRaDriel
Member #3,861
September 2003
|
Matt Weir: This is only a test picture extracted from an animation, the picture when in it final form is 'clipped' to the nearest non-masked pixel. Anyway thanks for the tip ! Andrei: I will try the _getpixel way. Also: the >>8 seems good too. "Code is like shit - it only smells if it is not yours" |
James Stanley
Member #7,275
May 2006
|
GIMP rules. |
GullRaDriel
Member #3,861
September 2003
|
Yeah perhaps. But GIMP does not do real time painting in my code. "Code is like shit - it only smells if it is not yours" |
|