3

カラークラスを作成していて、操作をmore(color、percentage)&less(color、percentage)に追加したいと考えています。これには、色の加算と減算ができる必要があり、算術演算に苦労しています。RGB、HSB(HSV)、またはHEXを使用して次のような操作を行うにはどうすればよいですか。

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

  • 青+黄=緑

また

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

  • 青+.5*黄=濃い緑

減算するために、私はそれについて非常に漠然とした概念を持っています:

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

  • オレンジ-黄色-.5*赤=黄色

編集: これまでの入力に感謝します。残念ながら、CYMを互いに追加してみましたが、CYMでは赤(255、0、0)〜=(0、1、1)で、それを青(0、0、255)に追加すると〜=(1、1 、0)CYMでは黒である(1、2、1)または(1、1、1)に等しくなります。

Hue Saturation Brightness(HSB)を使用して最も近くになりました。実際、それは赤の混乱を除いてすべての色の組み合わせで機能します。これは、赤が色相の最初と最後にあるためだと思います(色相は度[0、360]を使用します)。

これ以上のご意見をいただければ幸いです。


編集2:

さて、それで、いじり回して夜を過ごした後、これは私が本当に満足している「もっと」方法です。

HSB(色相-彩度-明るさ)カラーモデルを使用しています。CYMが機能しなかった理由を聞かないでください。私は色の初心者です。プリンターがどのように色をブレンドするかを見ると、うまくいくように見えます。私はHSBモデルが大好きで、それに加えて、カラーピッカーを使用したときにフォトショップが表示するものも気に入っています。

答えとして追加しましたので、皆さんの感想をお聞かせください!再度、感謝します!


どんな助けでも素晴らしいでしょう!

ありがとう、マット

4

7 に答える 7

3

RGB カラー スペースを使用する 1 つの解決策は、赤、緑、値などの色を内部的に表現することです。16 進表現が必要な場合は、現在の値から 1 つを作成して送り返します。

moreおよびメソッドはless、現在の赤、緑、または青の値を単純に操作します。

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

次のように16進文字列に変換します

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

文字列を RGB コンポーネントなどに変換する'orange-green'ことは、多少異なる問題です。

于 2010-07-19T05:56:09.653 に答える
2

混色にはさまざまなモデルがあります。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']);、アクアカラーのRGBA16進文字列を提供する必要があります。

単語変換の場合、色の総光を合計して、色が「暗い」、「通常」、「明るい」のいずれであるかを推測できます。また、「緑」、「オレンジ」などの色相を取得し、色を説明する語彙を構築することもできます。

于 2010-07-19T06:04:45.143 に答える
2

あなたが得ることができる最も近いのは、幸いなことに、RGBの逆であるCMYカラーモデルだと思います.

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) となり、これは緑色です

アップデート:

0 から 1 は、標準 RGB の 0 から 255 に相当する、無色およびフルカラーの便利な表現です。

「これは明らかに間違っている。シアン=青はどうなの?」と疑問に思っている人は、CMY != アートカラーであることも理解しておいてください。実際、アートの色はどの原色モデルとも一致しないため、これはアートに絵の具を混ぜて得られると期待される種類の色を得るための合理的な仮定にすぎません。

于 2010-07-19T06:17:19.877 に答える
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 );
}

それが役立つことを願っています!

編集:(これを行った後)スレッドに追いついたところ、0xFFFF00 + 0x0000FF で白ではなく緑を作成する必要があることがわかりました。

于 2010-07-19T08:53:16.720 に答える
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 

これは、はるかに複雑な色の相互作用を説明する非常に簡単な方法であることを付け加えなければなりません...

于 2010-07-19T11:50:30.393 に答える
1

減法原色について読んだ後、 RYB カラーモデルについて読むことができます。

RYB から RGB への変換はそれほど簡単ではないようです。この計算機(およびその背後にある JavaScript) を確認してください。

于 2010-07-19T08:24:42.933 に答える
0
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;
}

メソッドについてさらに説明が必要な場合、またはここで何か問題がある場合は、お知らせください。私はそれが美しく働くと言わなければなりません!less($color, $percent)また、代わりに色を差し引くことを除いて同じであることに注意してください。Less はまだ直感的に理解できません (黄緑 - 緑 = 茶色) が、計算は正しいと確信しています。あなたのご親切に感謝します!

于 2010-07-19T21:15:16.307 に答える