2

I have been struggling to combine two ARGB values - despite a lot of reading e.g. here... How to mix two ARGB pixels?

I am not getting the result I am expecting - or what I am expecting is wrong; if someone could suggest a function to do this, it would be great.

I want to combine:

  1. ColorA (red = 255, green = 255, blue = 0, alpha = 100)

  2. ColorB (red = 0, green = 0, blue = 100, alpha = 200)

And output the value in Red, Green, Blue, Alpha format.

I am expecting an output as follows (the greenish central color):

enter image description here

Thanks so much for helping this foolish coder!

Community
  • 1
  • 1
  • The problem here is that you haven't specified what you are expecting to happen. There are various ways to "combine" two colors. – BoltClock Oct 04 '15 at 09:49
  • There are lots of ways to combine two colours; eg. could take the hue from one and the value, saturation and alpha from the other; equally you could average each attribute. You need to define how you want them combined. – Richard Oct 04 '15 at 09:49
  • @Richard: lol, great minds ;) – BoltClock Oct 04 '15 at 09:49
  • :) This is why I request help. I hope the edit with added image helps you help me! Ta –  Oct 04 '15 at 09:58

1 Answers1

1

Like most questions, one ends up answering it one self:

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;
}

Source: Color mixing in android

Community
  • 1
  • 1