1

このActionScriptサンプルに出くわしました。これは、波形を使用して、ループを介して一度に1行ずつカラースペクトルを描画する方法を示しています。

ただし、各RGBチャネルの波形位置により、色が欠落しているカラースペクトル(純粋な黄色、シアン、マゼンタ)が作成されるため、スペクトルは不完全です。

描画されたカラースペクトルがすべての色を示すように、この問題を解決するにはどうすればよいですか?

// Loop through all of the pixels from '0' to the specified width.
for(var i:int = 0; i < nWidth; i++)
    {
    // Calculate the color percentage based on the current pixel.
    nColorPercent = i / nWidth;

    // Calculate the radians of the angle to use for rotating color values.
    nRadians = (-360 * nColorPercent) * (Math.PI / 180);

    // Calculate the RGB channels based on the angle.
    nR = Math.cos(nRadians)                   * 127 + 128 << 16;
    nG = Math.cos(nRadians + 2 * Math.PI / 3) * 127 + 128 << 8;
    nB = Math.cos(nRadians + 4 * Math.PI / 3) * 127 + 128;

    // OR the individual color channels together.
    nColor  = nR | nG | nB;
    }

更新されたソリューション


興味のある方のために、上記の問題に対処するために私が書いた解決策を以下に示します。RGB波形は、フルカラースペクトルの作成には使用されません。また、コードは柔軟であるため、生成されたスプライトに独自のサイズと色の変数を割り当てることができます。この例の色変数は、完全なカラースペクトルを生成するために、赤、黄、緑、シアン、青、マゼンタ、赤です。

/*
//SpectrumGradient Object Call

var spectrum:SpectrumGradient = new SpectrumGradient(stage.stageWidth, stage.stageHeight, 0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF, 0xFF0000);
this.addChild(spectrum);
*/


package
{
    import flash.display.BitmapData;
    import flash.display.CapsStyle;
    import flash.display.GradientType;
    import flash.display.LineScaleMode;
    import flash.display.Sprite;
    import flash.geom.Matrix;

    public class SpectrumGradient extends Sprite
        {
        public function SpectrumGradient(spriteWidth:Number, spriteHeight:Number, ...spriteColors)
            {
            //Setup spectrum sprite
            var spectrum:Sprite = new Sprite();
            var spectrumAlphas:Array = new Array();
            var spectrumRatios:Array = new Array();
            var spectrumPartition:Number = 255 / (spriteColors.length - 1);

            for (var pushLoop:int = 0; pushLoop < spriteColors.length; pushLoop++)
                {
                spectrumAlphas.push(1);
                spectrumRatios.push(pushLoop * spectrumPartition);
                }

            //Create spectrum sprite as evenly distributed linear gradient using supplied spriteColors
            var spectrumMatrix:Matrix = new Matrix();
            spectrumMatrix.createGradientBox(spriteWidth, spriteHeight);
            spectrum.graphics.lineStyle();
            spectrum.graphics.beginGradientFill(GradientType.LINEAR, spriteColors, spectrumAlphas, spectrumRatios, spectrumMatrix);
            spectrum.graphics.drawRect(0, 0, spriteWidth, 1);
            spectrum.graphics.endFill();

            //Assign bitmapData to the spectrum sprite
            var bitmapData:BitmapData = new BitmapData(spectrum.width, spectrum.height, true, 0);
            bitmapData.draw(spectrum);

            var pixelColor:Number;

            for (var i:int = 0; i < spriteWidth; i++)
                {
                //Retrieve the color number for each pixel of the spectrum sprite
                pixelColor = bitmapData.getPixel(i, 0);

                //Create new matrices for the white and black gradient lines
                var matrixWhite:Matrix = new Matrix();
                matrixWhite.createGradientBox(1, spriteHeight / 2, Math.PI * 0.5, 0, 0);
                var matrixBlack = new Matrix();
                matrixBlack.createGradientBox(1, spriteHeight / 2, Math.PI * 0.5, 0, spriteHeight / 2);

                //Each slice of the sprite is composed of two vertical lines:  the first fades from white to the pixelColor, the second fades from pixelColor to black
                graphics.lineStyle(1, 0, 1, false, LineScaleMode.NONE, CapsStyle.NONE);
                graphics.lineGradientStyle(GradientType.LINEAR, [0xFFFFFF, pixelColor], [100, 100], [0, 255], matrixWhite);
                graphics.moveTo(i, 0);
                graphics.lineTo(i, spriteHeight / 2);
                graphics.lineGradientStyle(GradientType.LINEAR, [pixelColor, 0], [100, 100], [0, 255], matrixBlack);
                graphics.moveTo(i, spriteHeight / 2);
                graphics.lineTo(i, spriteHeight);
                }

            }
        }
}
4

1 に答える 1

4

一度にすべての色を使用することはできません。すべてのRGBカラー、つまり256 x 256 x 256であるため、すべてを表示するには4096x4096ピクセルが必要です。

また、それらすべてを表示する「自然な」/賢明な方法はありません。少なくとも今まで、本当に意味のある2次元の色空間を思いついた人は誰もいません。色を表示するには、常に2を選択する必要があります。そのため、一般的なカラーチューザーは、色相スライダーと明度/彩度平面、または色相/彩度平面と明度スライダーのいずれかを使用します。

また、最初の(長方形の)スペクトルは、2つの重ね合わせた勾配で簡単に描画できることにも注意してください。色相は水平、明度は垂直(半透明)です。より速く、完全にスムーズです(ズームすると、個々の線は表示されません)。

編集:これは、単一のグラデーションでこれを実現する方法の実際の例です。これは、明らかな理由から望ましいことです。

package  {
    import flash.display.*;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;

    public class GradientTest extends Sprite {

        public function GradientTest() {
            var colors:Array = [0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF, 0xFF0000];
            var part:Number = 0xFF / (colors.length-1);
            var ratios:Array = [], alphas:Array = [];
            var m:Matrix = new Matrix();
            m.createGradientBox(500, 20);
            for (var i:int = 0; i < colors.length; i++) {
                ratios.push(part * i);
                alphas.push(100);
            }

            this.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, m);
            this.graphics.drawRect(0, 0, 500, 20);

            //just to get the RGB values under the mouse:
            var b:BitmapData = new BitmapData(this.width, this.height, true, 0);
            b.draw(this);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, function (e:Event):void {
                if (hitTestPoint(mouseX, mouseY)) {
                    var s:String = b.getPixel(mouseX, mouseY).toString(16);
                    while (s.length < 6) s = "0" + s;
                    trace("#" + s);                 
                }
            });
        }   
    }
}

波形を使用するアプローチは、釘を探すハンマーに少し似ています。ビット演算と三角法が優れたツールであるという理由だけで、はるかに単純なソリューションよりもそれらを優先する必要があるという意味ではありません。

于 2010-03-29T07:54:49.013 に答える