1

I'm trying to create a method that mixes two ARGB colors (the second one being on top) to a color with an alpha of 0xFF, i could just be blind but after 30 minutes of googling i can't seem to find a way to do this. Also this method has to be decently fast because all the other methods i tried that didn't work (for me?) slowed my program down from 200FPS to 40FPS.

For example if i would do mix(0xFF0F1F3F, 0x7FFFFFFF) i would get light blue-ish color and mix(0x7FFFFFFF, 0xFF0F1F3F) would return 0xFF0F1F3F because it has an alpha of 0xFF.

My current code:

private int mix(int argbA, int argbB) {
    int argbC = 0;
    // Color mixing code
    return argbC;
}
DutChen18
  • 1,133
  • 1
  • 7
  • 24
  • can you be a bit more specific about 'mixing' ? do you want to mediate each color channel (including alpha) ? – Martin Frank May 19 '15 at 05:03
  • @MartinFrank I want to mix the RGB values depending on the two alpha values. And the new alpha value always needs to be `0xFF`. – DutChen18 May 19 '15 at 05:17
  • ok, i'll adjust my answer - gotta get coffe first ^^ – Martin Frank May 19 '15 at 05:22
  • i guess you have two answers that show you how it works - but i think none of them solves your problem - i guess you'll have to write your own mixing but the answers will give you some hints on how you would do it ... – Martin Frank May 19 '15 at 05:44
  • Possibly a duplicate of http://stackoverflow.com/questions/726549/algorithm-for-additive-color-mixing-for-rgb-values – Raniz May 19 '15 at 06:06

2 Answers2

0

ok, mediationg argb channels will be

public int mediateARGB(int c1, int c2){
    int a1 = (c1 & 0xFF000000) >>> 24;
    int r1 = (c1 & 0x00FF0000) >> 16;
    int g1 = (c1 & 0x0000FF00) >> 8;
    int b1 = (c1 & 0x000000FF) ;

    int a2 = (c2 & 0xFF000000) >>> 24;
    int r2 = (c2 & 0x00FF0000) >> 16;
    int g2 = (c2 & 0x0000FF00) >> 8;
    int b2 = (c2 & 0x000000FF) ;

    int am = (a1 + a2) / 2;
    int rm = (r1 + r2) / 2;
    int gm = (g1 + g2) / 2;
    int bm = (b1 + b2) / 2;

    int m = (am << 24) + (rm << 16) + (gm << 8) + bm; 


    return m;
}
Martin Frank
  • 3,445
  • 1
  • 27
  • 47
0
private int mix(int argbA, int argbB) {
  // calculate how much to take from each color
  double alpha1 = ((argbA & 0xFF000000) >> 24);
  double alpha2 = ((argbB & 0xFF000000) >> 24);
  // double f = 256 / (alpha1 + alpha2);
  // alpha1 *= f;
  // alpha2 *= f;
  alpha1 = 256 - alpha2;
  int out = 0xFF000000;
  // out |= ((int)(((argbA & 0xFF0000) >> 16) * alpha1 + ((argB & 0xFF0000) >> 16) * alpha2)) << 16;
  // out |= ((int)(((argbA & 0xFF00) >> 8) * alpha1 + ((argB & 0xFF00) >> 8) * alpha2)) << 8;
  // out |= ((int)((argbA & 0xFF) * alpha1 + (argB & 0xFF) * alpha2));
  out |= ((int)((argbA & 0xFF0000) * alpha1 + (argB & 0xFF0000) * alpha2)) & 0xFF0000;
  out |= ((int)((argbA & 0xFF00) * alpha1 + (argB & 0xFF00) * alpha2)) & 0xFF00;
  out |= ((int)((argbA & 0xFF) * alpha1 + (argB & 0xFF) * alpha2));
  // this would be an error I think: out |= ((int)((argbA & 0xFFFFFF) * alpha1 + (argB & 0xFFFFFF) * alpha2));
  return out;
}
maraca
  • 8,468
  • 3
  • 23
  • 45
  • As i said, "`mix(0x7FFFFFFF, 0xFF0F1F3F)` would return `0xFF0F1F3F` because it has an alpha of `0xFF`". The second value needs to be on top of the first value. – DutChen18 May 19 '15 at 05:49
  • @DutChen18 Ok I see, no problem, all we need to do is adjust factors alpha1 and alpha2. – maraca May 19 '15 at 05:56
  • @DutChen18 not sure if this is what you want but I think we can leave alpha2 as is and take 256 - alpha2 for alpha1 or do you also want to take into account the alpha channel of 1? – maraca May 19 '15 at 06:05