22

I am working on application in which i have five colors:Red,Green,Blue,Yellow,purple

I want to implement color mixing from those colors:such that like there are five button for each color.

User touch whichever color button this color mix with previously drawn color.

I have not any clue how to add two color codes and get third color.

EDitED:

I have to also set this color to imageview's bitmap

how can i set this?

chikka.anddev
  • 9,569
  • 7
  • 38
  • 46

8 Answers8

53

Since April 2015 you can use blendARGB method from v4 support library:

int resultColor = ColorUtils.blendARGB(color1, color2, 0.5F);

Ratio value has to be 0.5 to achive even mix.

Szymon Grochowiak
  • 640
  • 1
  • 5
  • 6
  • Perfect also for setting lighter/darker hues of a color! – mjp66 Feb 22 '18 at 10:19
  • 3
    The 3rd argument is ratio(the proportion while blending the colors). eg. If you want 30% of color1 & 70% of color2, then do ColorUtils.blendARGB(***, ***, 0.3F); – Pranav Mahajan Mar 11 '18 at 00:37
19

An alternative answer:

You can mix the bits in the hexs:

public static int mixTwoColors( int color1, int color2, float amount )
{
    final byte ALPHA_CHANNEL = 24;
    final byte RED_CHANNEL   = 16;
    final byte GREEN_CHANNEL =  8;
    final byte BLUE_CHANNEL  =  0;

    final float inverseAmount = 1.0f - amount;

    int a = ((int)(((float)(color1 >> ALPHA_CHANNEL & 0xff )*amount) +
                   ((float)(color2 >> ALPHA_CHANNEL & 0xff )*inverseAmount))) & 0xff;
    int r = ((int)(((float)(color1 >> RED_CHANNEL & 0xff )*amount) +
                   ((float)(color2 >> RED_CHANNEL & 0xff )*inverseAmount))) & 0xff;
    int g = ((int)(((float)(color1 >> GREEN_CHANNEL & 0xff )*amount) +
                   ((float)(color2 >> GREEN_CHANNEL & 0xff )*inverseAmount))) & 0xff;
    int b = ((int)(((float)(color1 & 0xff )*amount) +
                   ((float)(color2 & 0xff )*inverseAmount))) & 0xff;

    return a << ALPHA_CHANNEL | r << RED_CHANNEL | g << GREEN_CHANNEL | b << BLUE_CHANNEL;
}
Ratata Tata
  • 2,781
  • 1
  • 34
  • 49
19

SlidingTabStrip has really useful method for blending colors, looks great when used with ViewPager:

private static int blendColors(int color1, int color2, float ratio) {
    final float inverseRation = 1f - ratio;
    float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
    float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
    float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
    return Color.rgb((int) r, (int) g, (int) b);
}
Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
Marqs
  • 17,800
  • 4
  • 30
  • 40
7

If colors are in RGB space, it is pretty simple (but the result is sometimes not that satisfying):

public int mixColors(int col1, int col2) {
    int r1, g1, b1, r2, g2, b2;

    r1 = Color.red(col1);
    g1 = Color.green(col1);
    b1 = Color.blue(col1);

    r2 = Color.red(col2);
    g2 = Color.green(col2);
    b2 = Color.blue(col2);

    int r3 = (r1 + r2)/2;
    int g3 = (g1 + g2)/2;
    int b3 = (b1 + b2)/2;

    return Color.rgb(r3, g3, b3);
}

If you want to use other color spaces, search Wikipedia and find HSL color space. You also have some libraries to do that for you.

Then you will have to read this question: Calculation of a mixed color in RGB

Community
  • 1
  • 1
Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
  • thnx for reply bt i have 5 colors not only rgb. – chikka.anddev May 20 '11 at 10:07
  • RGB are the components of each color. So you have 5 times RGB. You need to combine the answer from Luis Miguel Serrano and mine. – Vincent Mimoun-Prat May 20 '11 at 10:15
  • Thanx for reply.But i need more color space with using above function on five mixes it will stay on constant color.What should better sol for more color space mixing? – chikka.anddev May 27 '11 at 05:59
  • @MarvinLabs you are aware that your answer as well the linked one are very bad for mixing RGB colors (you say that yourself), so why include it ? Barycenter interpolation gives much more meaningful results for RGB (which is a bad color system nevertheless). With three colors, some yellow one, a brown one, and a pink, you would get this: http://i.imgur.com/thLiR.png. It can be extended to n points. – mmgp Jan 05 '13 at 13:18
6

See ArgbEvaluator (since API 11) http://developer.android.com/reference/android/animation/ArgbEvaluator.html

IuriiO
  • 611
  • 7
  • 13
  • Great, I use it to tint colors having full lightness already, by blending the color with white. Works great. – Ridcully Dec 26 '14 at 10:13
  • Bizzre choice of API by android developers. Needlessly requires an instance. Needlessly takes Object parameters which promptly get cast to Integer. Should not be used in realtime drawing or animation code because of boxing and unboxing allocations. So you know. (Thanks to original poster; no thanks to the Android dev that wrote this attrocity).Better to just swipe oen of the other code fragments in this posting. – Robin Davies Jul 13 '15 at 15:12
3

This example may by useful if you want blend two colors (foreground and background). Based on Orlando Leite answare and wikipedia http://en.wikipedia.org/wiki/Alpha_compositing, proper way to blend two colors with alpha is:

public static int MergeColors(int backgroundColor, int foregroundColor) {
    final byte ALPHA_CHANNEL = 24;
    final byte RED_CHANNEL   = 16;
    final byte GREEN_CHANNEL =  8;
    final byte BLUE_CHANNEL  =  0;

    final double ap1 = (double)(backgroundColor >> ALPHA_CHANNEL & 0xff) / 255d;
    final double ap2 = (double)(foregroundColor >> ALPHA_CHANNEL & 0xff) / 255d;
    final double ap = ap2 + (ap1 * (1 - ap2));

    final double amount1 = (ap1 * (1 - ap2)) / ap;
    final double amount2 = amount1 / ap;

    int a = ((int)(ap * 255d)) & 0xff;

    int r = ((int)(((float)(backgroundColor >> RED_CHANNEL & 0xff )*amount1) +
            ((float)(foregroundColor >> RED_CHANNEL & 0xff )*amount2))) & 0xff;
    int g = ((int)(((float)(backgroundColor >> GREEN_CHANNEL & 0xff )*amount1) +
            ((float)(foregroundColor >> GREEN_CHANNEL & 0xff )*amount2))) & 0xff;
    int b = ((int)(((float)(backgroundColor & 0xff )*amount1) +
            ((float)(foregroundColor & 0xff )*amount2))) & 0xff;

    return a << ALPHA_CHANNEL | r << RED_CHANNEL | g << GREEN_CHANNEL | b << BLUE_CHANNEL;
}

In this case alpha channel is used to compute percentage RGB share in blending. Background color may be visible only i foreground alpha is smaller than 100%

yaneq6
  • 151
  • 8
1

In Android you can work with Colors using the Color class.

With this class, you can access the Red, Green and Blue components of a color, so that you can then perform operations with them and apply color algorithms. You can extract the color components from a color int in this way:

int color = Color.BLACK;

int red, green, blue;
red = Color.red(color);
green = Color.green(color);
blue = Color.blue(color);

Each value must be between 0 and 255, so when you mix two colors together, you should either divide the value by two, to make sure the final result is within the same interval, or apply another algorithm bearing in mind the fact that each color component has a different weight for the luminance of a pixel.

Luis Miguel Serrano
  • 5,029
  • 2
  • 41
  • 41
  • Bonus point for spotting Color.red, Color.green, Color.blue &c. Should be using these. Although the accepted answer (mixTwoColors) provides a complete implementation that could be made slightly more stylish with the Color.xxx methods. – Robin Davies Oct 21 '14 at 04:49
0

In previous answer "amount2" is calculated wrongly. Should be:

final double amount2 = ap2 / ap;

So, the whole code will look like:

public static int MergeColors(int backgroundColor, int foregroundColor) {
    final byte ALPHA_CHANNEL = 24;
    final byte RED_CHANNEL   = 16;
    final byte GREEN_CHANNEL =  8;
    final byte BLUE_CHANNEL  =  0;

    final double ap1 = (double)(backgroundColor >> ALPHA_CHANNEL & 0xff) / 255d;
    final double ap2 = (double)(foregroundColor >> ALPHA_CHANNEL & 0xff) / 255d;
    final double ap = ap2 + (ap1 * (1 - ap2));

    final double amount1 = (ap1 * (1 - ap2)) / ap;
    final double amount2 = ap2 / ap;

    int a = ((int)(ap * 255d)) & 0xff;

    int r = ((int)(((float)(backgroundColor >> RED_CHANNEL & 0xff )*amount1) +
            ((float)(foregroundColor >> RED_CHANNEL & 0xff )*amount2))) & 0xff;
    int g = ((int)(((float)(backgroundColor >> GREEN_CHANNEL & 0xff )*amount1) +
            ((float)(foregroundColor >> GREEN_CHANNEL & 0xff )*amount2))) & 0xff;
    int b = ((int)(((float)(backgroundColor & 0xff )*amount1) +
            ((float)(foregroundColor & 0xff )*amount2))) & 0xff;

    return a << ALPHA_CHANNEL | r << RED_CHANNEL | g << GREEN_CHANNEL | b << BLUE_CHANNEL;
}
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/33665975) – Entea Jan 24 '23 at 10:49