12

Is it possible to subtract a color from another one ?

Example (correct me if i'm wrong):

If i subtract red and green from white, i am expecting the result to be blue.

var white = 0xFFFFFF,
    red = 0xFF0000,
    result = white - red;
console.log(result); //65535 <-- what is that ? can it be converted to 0x00FFFF ?

[update]

Thanks to Rocket's answer, it turned out i needed a function() to convert my results into an actual color.

Here is the final working example:

var toColor = function ( d ) {
       var c = Number(d).toString(16);
       return "#" + ( "000000".substr( 0, 6 - c.length ) + c.toUpperCase() );
    },
    white = 0xFFFFFF,
    red = 0xFF0000,
    green = 0x00FF00,
    result = toColor( white - red - green );

console.log( result ); // logs the expected result: "#0000FF"
Community
  • 1
  • 1
Pierre
  • 18,643
  • 4
  • 41
  • 62
  • How are you substracting it? Are you using RGB or CMYK, are you mixing colors or light? – TJHeuvel Jan 25 '12 at 16:09
  • 2
    Direct substraction won't work. Consider `0xCC3366 - 0xDD0011` -> `0xFFFF FFFF FFEF 3355`. On the other hand, your 65535 is just the decimal (base 10) representation of 0xFFFF - a simple base conversion will give you FFFF for display purposes, but internally both numbers are identical – Marc B Jan 25 '12 at 16:12
  • 2
    `65535 == 0x00FFFF` is `true`, your first approach works, you are subtracting RGB colors. – Dan D. Jan 25 '12 at 16:13
  • @TJHeuvel, I agree with you about subtracting colors with CMYK because subtractive color systems ordinarly utlize cyan, magenta and yellow dye spectral filters since the cyan, magenta and yellow filters are "notch" filters which permit a greater transmission of light energy than narrowband red, green or blue "bandpass" filters. Therefore, color subtraction is more complex than piecewise subtraction and flooring. What is your opinion of CMYK subtractive color systems for aerospace applications? – Frank Mar 06 '16 at 00:27

2 Answers2

9

Your white-red works fine, it's just that JavaScript represents the values as base 10 values. You need to convert them back to base 16 (hex). Check out this answer, to convert the value back to hex.

var white = 0xFFFFFF, // Stored as 16777215
    red = 0xFF0000, // Stored as 16711680
    result = white - red; // 16777215 - 16711680 = 65535
console.log(result); // It's stored as base 10, so it prints 65535
var resultHex = result.toString(16); // 'ffff', converted back to hex
Community
  • 1
  • 1
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • 3
    `0x001100 - 0x000011 = 0x0010ef`; subtracting dark blue from dark green should not yield bright blue. Piecewise subtraction and flooring is the only correct way to subtract colors. – Phrogz Jan 25 '12 at 21:34
  • @Phrogz: Ah, that makes sense. Didn't realize that would happen. – gen_Eric Jan 25 '12 at 21:52
  • @Phrogz, Suppose a composite color value consists of a coherent dark green laser beam superimposed on a dark blue incoherent light background , could we still use your excellent piecewise subtraction formula to filter out the coherent dark green laser beam from the composite color value? Thank you. – Frank Mar 05 '16 at 13:19
  • Is subtracting the color value of a coherent laser dot from a incoherent cockpit background tinged with laser dot(s) a nonlinear image subtraction problem? – Frank Mar 06 '16 at 08:33
6

I'm just assuming you are using RGB, because there are plenty of other ways to mix colors. You have to represent a color into 3* different parts, R G and B.

//            R  G  B 
var white = [ 1, 1, 1]; 
var red =   [ 0, 0, 0 ];
var result = [ white[0] - red[0], white[1] - red[1], white[2] - red[2] ;

To substract the color you have to substract each component of the color, and perhaps convert it back to hex later on.

* You might want to add Alpha later on

TJHeuvel
  • 12,403
  • 4
  • 37
  • 46