Mixing colors (adding and subtracting colors), as in Art Class!

I am creating a color class, and I want to add additional operations (color, percent) and less (color, percent). This requires the ability to add and subtract colors, and it's hard for me to do arithmetic. How to use RGB or HSB (HSV) or HEX to perform operations such as:

Operation - echo color('blue')->more('yellow', 100%);

  • blue + yellow = green

or

Operation - echo color('blue')->more('yellow', 50%);

  • blue +.5 * yellow = dark green

For subtraction, I have a very vague idea about this:

Operation - echo color('orange-yellow')->less('red', 50%);

  • orange yellow -.5 * red = yellow

EDIT: Alright, thanks for your input. I tried to add CYM to each other, unfortunately, in red (255, 0, 0) ~ = (0, 1, 1) in CYM, and then if you add this in blue (0, 0, 255) ~ = (1 , 1, 0) it will be equal to (1, 2, 1) or (1, 1, 1), which is black in CYM.

Hue Saturation (HSB). , . , ( [0, 360]).

!


2:

, "" , .

HSB (Hue-Saturation-Brightness), , CYM . . , , , . HSB , , Photoshop, .

, , , , ! !


!

, Matt

+3
7

, RGB, - , , . , .

more less , .

public function more($color, $percentage) {
    $this->color[$color] += $this->color[$color] * $percentage;
}

public function toHex() {
    $red = $this->color['red'];
    $green = $this->color['green'];
    $blue = $this->color['blue'];
    return sprintf("%02X%02X%02X", $red, $green, $blue);
}

, 'orange-green' , RGB - .

+3

. RGBA.

$colors = array(
    'opaque_green' => '00FF00FF',
    'transparent_blue' => '0000FF33',
);


public function toHex($red, $green, $blue, $alpha) {
    return sprintf("%02X%02X%02X%02X", $red, $green, $blue, $alpha);
}

//Reverted to british spelling :P
public function mixColours($colours) {
   $red = 0; $blue = 0; $green = 0; $alpha = 256; 
   foreach($colours as $colour) {
       $alpha_mod = hexdec(substr($colour, 6, 2)) / 256;
       $red   += $alpha_mod * hexdec(substr($colour, 0, 2));
       $green += $alpha_mod * hexdec(substr($colour, 2, 2));
       $blue  += $alpha_mod * hexdec(substr($colour, 4, 2));
   }
   $num_colours = count($colours);
   return toHex($red/$num_colours, $green/$num_colours, $blue/$num_colours, $alpha);
}

, mixColours(array($colors['opaque_green'], $colors['transparent_blue']); RGBA aqua.

, "", "" "". "", "" .. .

+2

, CMY, , , RGB.

C = 1 - R
M = 1 - G
Y = 1 - B

, ( CMY - --), C = , M = , Y = , . :

  • (1, 0, 0)
  • (0, 0, 1)
  • + (1, 0, 1)
  • RGB (0, 1, 0)

Update:

0 1 - , 0 255 RGB.

, : ", , , = ?", , CMY!= . , - , , , , .

+2

!

:

// examples
$c = Color(0x08090a)->more( 0xFF0000 , 100 )->remove(0x110000)->decrease(35)->add(0x002314);
$c->red = 0xF2;
$c->red->decrease(25);

, - , , , , , - , Color() , .

<?php

class ColorElement {

    private $value;

    public function __construct( $value = 0 )
    {
        $this->setValue( $value );
    }

    public function add( $value )
    {
        $value = self::fixValue($value);
        $this->value = self::fixValue( $this->value + $value );
        return $this;
    }

    public function remove( $value )
    {
        $value = self::fixValue($value);
        $this->value = self::fixValue( $this->value - $value );
        return $this;
    }

    public function increase( $percentage=100 )
    {
        $percentage = self::fixPercentage($percentage);
        $this->value = self::fixValue( $this->value + (int)(($this->value/100)*$percentage) );
        return $this;
    }

    public function decrease( $percentage=100 )
    {
        $percentage = self::fixPercentage($percentage);
        $this->value = self::fixValue( $this->value - (int)(($this->value/100)*$percentage) );
        return $this;
    }

    public function less( $value , $percentage=100 )
    {
        $percentage = self::fixPercentage($percentage);
        $value = self::fixValue($value);
        $this->value = self::fixValue( $this->value - (int)(($value/100)*$percentage) );
        return $this;
    }

    public function more( $value , $percentage=100 )
    {
        $percentage = self::fixPercentage($percentage);
        $value = self::fixValue($value);
        $this->value = self::fixValue( $this->value + (int)(($value/100)*$percentage) );
        return $this;
    }

    public function setValue( $value )
    {
        $this->value = self::fixValue($value);
        return $this;
    }

    public function getValue()
    {
        return $this->value;
    }

    public function __toString()
    {
        return sprintf('%02X' , $this->value);
    }

    public static function fixValue( $value )
    {
        return $value < 0 ? 0 : ($value > 255 ? 255 : $value);
    }

    public static function fixPercentage( $percentage )
    {
        return $percentage < 0 ? 0 : ($percentage > 100 ? 100 : $percentage);
    }

}

class Color {

    private $_red;
    private $_green;
    private $_blue;

    public function __construct( $hex=0x000000 )
    {
        $this->_red = new ColorElement();
        $this->_green = new ColorElement();
        $this->_blue = new ColorElement();
        $this->setColor($hex);
    }

    public function add( $hex )
    {
        list($red, $green, $blue) = self::hexRGB($hex);
        $this->_red->add( $red );
        $this->_green->add( $green );
        $this->_blue->add( $blue );
        return $this;
    }

    public function remove( $hex )
    {
        list($red, $green, $blue) = self::hexRGB($hex);
        $this->_red->remove( $red );
        $this->_green->remove( $green );
        $this->_blue->remove( $blue );
        return $this;
    }

    public function increase( $percentage=100 )
    {
        $this->_red->increase( $percentage );
        $this->_green->increase( $percentage );
        $this->_blue->increase( $percentage );
        return $this;
    }

    public function decrease( $percentage=100 )
    {
        $this->_red->decrease( $percentage );
        $this->_green->decrease( $percentage );
        $this->_blue->decrease( $percentage );
        return $this;
    }

    public function less( $hex , $percentage=100 )
    {
        list($red, $green, $blue) = self::hexRGB($hex);
        $this->_red->less( $red , $percentage );
        $this->_green->less( $green , $percentage );
        $this->_blue->less( $blue , $percentage );
        return $this;
    }

    public function more( $hex , $percentage=100 )
    {
        list($red, $green, $blue) = self::hexRGB($hex);
        $this->_red->more( $red , $percentage );
        $this->_green->more( $green , $percentage );
        $this->_blue->more( $blue , $percentage );
        return $this;
    }

    public function setColor( $hex )
    {
        list($this->red, $this->green, $this->blue) = self::hexRGB($hex);
        return $this;
    }

    public function __set( $color , $value )
    {
        if( !in_array( $color, array('red','green','blue') ) ) return;
        $this->{'_'.$color}->setValue( $value );
    }

    public function &__get( $color )
    {
        if( !in_array( $color, array('red','green','blue') ) ) return;
        return $this->{'_'.$color};
    }

    public function __toString()
    {
        return '0x' . $this->_red . $this->_green . $this->_blue;
    }

    public static function hexRGB( $hex )
    {
        return array( $hex >> 16 & 0xFF , $hex >> 8 & 0xFF , $hex & 0xFF );
    }

}

function Color( $hex=0x000000 ) {
    return new Color( $hex );
}

, !

edit: ( ) , , 0xFFFF00 + 0x0000FF , - , rgb - !

+2

, RYB.

, RYB RGB , ( javascript ).

+1

/ :

+ = (, ..),

( ), : + =

? ( ), " ":

blue(#0000FF) +sub yellow(#FFFF00) = black(#000000)
because
blue_complement(#FFFF00) +add yellow_complement(#0000FF) = #(FFFFFF) --> white which is black complement

( - , ) ? "", (# 00FFFF) :

cyan(#00FFFF) +sub yellow(#FFFF00) = green(#00FF00)
because
cyan_complement(#FF0000) +add yellow_complement(#0000FF) = #(FF00FF) --> magenta 

, , ...

+1
public function more($color, $percent = 100) {

    $percent = trim($percent, '% ');
    $percent /= 100;

    // Dictionary lookup that maps 'yellow' to #ffff00 and 'indianred' to #cd5c5c
    $color = $this->_map_color($color);

    // Creates a new Color - this will automatically compute RGB, CYM, HEX, and HSB color models
    $color = new Color($color);

    // $this->color is current color , $color is the color to be added to original

    // Allows hue to be both 360 degrees and 0 degrees
    if($this->color->hsb('h') == 0) {
        if($color->hsb('h') > 180) {
            $h = 360;
        } else {
            $h = 0;
        }
    } else {
        $h = $this->color->hsb('h');
    }

    // Computes weights of colors - original:addedColor
    // 100% added means perfect blend 50:50
    // 50% means 75:25
    // 0% means no color added 100:0
    $c2_weight = $percent / 2;
    $c1_weight = 1 - $c2_weight;

    // Compute the hue, saturation, brightness values using the weights
    $hsb[0] = round($c1_weight * $h + $c2_weight * $color->hsb('h'));
    $hsb[1] = round($c1_weight * $this->color->hsb('s') + $c2_weight * $color->hsb('s'));
    $hsb[2] = round($c1_weight * $this->color->hsb('b') + $c2_weight * $color->hsb('b'));

    $hsb = implode(' ', $hsb);

    // Change current color into the new computed HSB value.    
    $this->color = $this->color->hsb($hsb);

    return $this;
}

If the method needs a more detailed explanation or if you see something wrong, let me know! I have to say it works great! I will also note what less($color, $percent)is the same, except that you subtract the color instead. Less still has no intuitive meaning for me (yellow-green - green = brown), but I'm sure the calculation is correct. Thanks again for your help!

0
source

Source: https://habr.com/ru/post/1755254/


All Articles