Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (565) Games in Android Showcase (152) games submitted by our members Games in WIP (607) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
 Home Help Search Login Register
Pages: [1]
 ignore  |  Print
 Weighted average of colors [solved]  (Read 2688 times) 0 Members and 1 Guest are viewing this topic.
nhmllr

Senior Devvie

Medals: 1
Projects: 3

 « Posted 2012-09-06 19:21:49 »

I'm trying to make a gradient effect. I want to make a method that returns returns a color for a position on a gradient. So for example, if variable "x" can be anything from 0 to 9, if x was 0 I might want the method to return black. If x was 9, I might want it to return white, and if x was 2 I mighy want the function to return a dark gray. The colors don't have to be white and black, but any two colors. (The method would return a "Color" from the Java Color class)

I tried to make a weighted average for each rgb value and put them back together, but it doesn't work properly. The colors don't mix properly

 1  2  3  4  5  6 `Color gradientColor(float x){      int r = (int) (x*color1.getRed() + (length-x)*color2.getRed())/length;      int g = (int) (x*color1.getGreen() + (length-x)*color2.getGreen())/length;      int b = (int) (x*color1.getBlue() + (length-x)*color2.getBlue())/length;      return new Color(r*0xffff+g*0xff+b);   }`

"length" is the length of the gradient, which was 9 in the above example, and color1 might be white and color2 might be black

Thanks
jonjava
 « Reply #1 - Posted 2012-09-06 20:05:02 »

Hmm.

 1  2  3  4  5 `// x = 0: black, x = 1: whiteint red = 255*x;int green = 255*x;int blue = 255*x;return new Color( (red << 16) | (green << 8) | blue );`

nhmllr

Senior Devvie

Medals: 1
Projects: 3

 « Reply #2 - Posted 2012-09-06 20:08:08 »

Right, but that only works for black and white. In my applet I'm using many more colors and need a general solution for them.
 Games published by our own members! Check 'em out!
jonjava
 « Reply #3 - Posted 2012-09-06 20:11:39 »

if you substitute

 1 `return new Color(r*0xffff+g*0xff+b)`

for
 1 `return new Color( (r << 16) | (g << 8) | b )`

What happens?

[EDIT]: I'm not sure I'm getting the question, lemme try and re-read :o

 1  2  3  4  5  6  7  8 `public Color getColor(float x, Color c1, Color c2) {   float y = 1-x;   int red = (x*c1.getRed() + y*c2.getRed());   int grn = (x*c1.getGreen() + y*c2.getGreen());   int blu = (x*c1.getBlue() + y*c2.getBlue());   int col = (red << 16) | (grn << 8) | blu;   return new Color(col);}`

More like this? Or do you want to adjust only brightness or something?

nhmllr

Senior Devvie

Medals: 1
Projects: 3

 « Reply #4 - Posted 2012-09-06 20:42:33 »

Oh... I put in "return new Color( (r << 16) | (g << | b )" and it worked. Huh... I had only read about these bit-wise operators and never used them. I wonder why my implementation didn't work... Oh well, probably just messed up the math. Anyway, it works now. Thanks!
Riven
« League of Dukes »

« JGO Overlord »

Medals: 948
Projects: 4
Exp: 16 years

 « Reply #5 - Posted 2012-09-06 20:50:01 »

With this code:
 1 `x*0xff`
you multiply by 255.

Whereas with this code:
 1 `x<<8`
you multiply by 256.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
jonjava
 « Reply #6 - Posted 2012-09-06 21:04:21 »

An int can hold 32 bits of data. 32 bits == 4 bytes. Which further equals 1 int (I.e, an int is made up of 4 bytes).

A pixel/color is a bucket of data that holds 3 colours: Red, Green and Blue. Why? Because using those 3 colours we can trick the human eye to see over 16 million different colours (255 * 255 * 255).

So because an int can hold up to 4 bytes a pixel is usually represented as an int. Sometimes the last byte is used for transparency (Alpha).

You are saving the r, g and b values as ints which make them all look something like this:

0000 0000 0000 0000 0000 0000 0000 0000

With the last first (bits are read from right to left) 2 bytes (8 bits) actually representing the given colour value (0-255).

So to pack them all together into 1 int you need to combine the bits and shift the Red colour 2 bytes (16 bits) to the left and the Green byte 1 byte (8 bits) to the left using the universal bitwise or operator so that you get them in the nice RGB order.

Or you could simply create the java Colour object using the "Color(int, int, int)" contructor. and skip the whole bit combining business.

pjt33

« JGO Spiffy Duke »

Medals: 39
Projects: 4
Exp: 7 years

 « Reply #7 - Posted 2012-09-06 22:42:55 »

I tried to make a weighted average for each rgb value and put them back together, but it doesn't work properly. The colors don't mix properly
No, RGB isn't a very good colour space for interpolation. If you want to keep it simple, you could use HSV and Java's built-in conversions between RGB and HSV [1]; otherwise you can either explore JAI (might have some useful stuff - I haven't looked) or write some conversion code to and from La*b*, perhaps porting it from http://www.codeproject.com/Articles/19045/Manipulating-colors-in-NET-Part-1

Colour is quite a big topic. If you can understand Spanish, there's a 5 minute presentation I gave as a taster introduction to La*b* on Youtube at http://www.youtube.com/watch?v=5HdY4XzZ0Ws

[1] Although if you do this, beware that as far as I'm aware they still haven't fixed a bug I reported against it 9 years and 11 months ago. http://bugs.sun.com/view_bug.do?bug_id=4759386
sproingie

JGO Kernel

Medals: 202

 « Reply #8 - Posted 2012-09-07 00:49:20 »

While there's also colorspace issues when interpolating colors, the problem our unvowelled monkey friend had was merely an arithmetic error.

If you're not doing photo correction, HSV will probably be good enough.
loom_weaver

JGO Coder

Medals: 17

 « Reply #9 - Posted 2012-09-07 04:53:31 »

No, RGB isn't a very good colour space for interpolation.

This is important.  Take, for example, converting to grayscale.  A simple linear interpolation might do something like ((r+g+b)/255.0*3) * 255 and set all the r/g/b components to that value.  It ends up looking like crap.

This works much better:
 1  2  3 `val brightness = math.sqrt(0.259 * color.getRed   * color.getRed +                           0.587 * color.getGreen * color.getGreen +                           0.114 * color.getBlue  * color.getBlue)`

There are many other similar formulas available.  It's because the human eye is more sensitive to certain colors than others:
http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
 Games published by our own members! Check 'em out!
Roquen
 « Reply #10 - Posted 2012-09-07 15:02:16 »

I think I'd use one of the cheap uniform colorspaces...like whatever that integer-to-integer one used in H264 is or the old cinepak one for instance.
Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 Riven (10 views) 2015-04-01 18:27:05 ags1 (26 views) 2015-03-31 10:55:12 theagentd (13 views) 2015-03-27 23:08:20 wxwsk8er (54 views) 2015-03-20 15:39:46 Fairy Tailz (48 views) 2015-03-15 21:52:20 Olo (29 views) 2015-03-13 17:51:59 Olo (33 views) 2015-03-13 17:50:51 Olo (40 views) 2015-03-13 17:50:16 Olo (44 views) 2015-03-13 17:47:07 ClaasJG (61 views) 2015-03-10 11:36:42
 BurntPizza 21x LiquidNitrogen 21x KevinWorkman 18x EgonOlsen 17x theagentd 16x basil_ 16x Roquen 15x Varkas 12x wessles 11x 65K 11x Riven 9x Rayvolution 9x phu004 8x SHC 8x princec 8x Ashedragon 8x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org