YCrCb Gradient
YCrCb色空間で輝度を一定に保った状態でグラデーションを変化させてみる。
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.InterpolationMethod;
import flash.display.PixelSnapping;
import flash.display.Shape;
import flash.display.SpreadMethod;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
/**
* ...
* @author @kndys
*/
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var yPlaneH:BitmapData = new BitmapData(256, 256, false);
var yPlaneM:BitmapData = new BitmapData(256, 256, false);
var yPlaneL:BitmapData = new BitmapData(256, 256, false);
for (var uy:uint = 0; uy < 256; uy++)
{
for (var ux:uint = 0; ux < 256; ux++)
{
yPlaneH.setPixel(ux, uy, new YCrCbColor(0xff, ux, uy).toRGB());
yPlaneM.setPixel(ux, uy, new YCrCbColor(0x80, ux, uy).toRGB());
yPlaneL.setPixel(ux, uy, new YCrCbColor(0x00, ux, uy).toRGB());
}
}
var yImageH:Bitmap = new Bitmap(yPlaneH, PixelSnapping.NEVER, true);
var yImageM:Bitmap = new Bitmap(yPlaneM, PixelSnapping.NEVER, true);
var yImageL:Bitmap = new Bitmap(yPlaneL, PixelSnapping.NEVER, true);
var a:Number = (465.0 - 10 * 4) / 3;
var scale:Number = a / 256;
yImageH.scaleX = yImageH.scaleY = scale;
yImageM.scaleX = yImageM.scaleY = scale;
yImageL.scaleX = yImageL.scaleY = scale;
yImageH.x = yImageH.y = yImageL.x = yImageM.x = 10;
yImageM.y = yImageH.y + a + 10;
yImageL.y = yImageM.y + a + 10;
addChild(yImageH);
addChild(yImageM);
addChild(yImageL);
var dotH:WanderingDot = new WanderingDot(0x0, 0x80);
var dotM:WanderingDot = new WanderingDot(0x80, 0x80);
var dotL:WanderingDot = new WanderingDot(0xff, 0x80);
var dotsShape:Shape = new Shape();
addChild(dotsShape);
var colorH:uint;
var colorM:uint;
var colorL:uint;
var gradMat:Matrix = new Matrix();
var gradRect:Rectangle = new Rectangle(2 * 10 + a, 10, 465 - 3 * 10 - a, 465 - 2 * 10);
var xH:Number;
var yH:Number;
var xM:Number;
var yM:Number;
var xL:Number;
var yL:Number;
gradMat.createGradientBox(gradRect.width, gradRect.height, 0.5 * Math.PI, gradRect.x, gradRect.y);
addEventListener(Event.ENTER_FRAME, function(e:Event):void
{
dotH.update((4 * Math.random()) | 0);
dotM.update((4 * Math.random()) | 0);
dotL.update((4 * Math.random()) | 0);
colorH = yPlaneH.getPixel32(dotH.x, dotH.y);
colorM = yPlaneM.getPixel32(dotM.x, dotM.y);
colorL = yPlaneL.getPixel32(dotL.x, dotL.y);
xH = yImageH.x + dotH.x * scale;
yH = yImageH.y + dotH.y * scale;
xM = yImageM.x + dotM.x * scale;
yM = yImageM.y + dotM.y * scale;
xL = yImageL.x + dotL.x * scale;
yL = yImageL.y + dotL.y * scale;
graphics.clear();
graphics.beginGradientFill(GradientType.LINEAR, [colorH, colorM, colorL], [1, 1, 1], [0, 0x80, 0xff], gradMat, SpreadMethod.PAD, InterpolationMethod.LINEAR_RGB);
graphics.drawRect(gradRect.x, gradRect.y, gradRect.width, gradRect.height);
dotsShape.graphics.clear();
dotsShape.graphics.lineStyle(0, 0);
dotsShape.graphics.drawRect(xH-1, yH-1, 3, 3);
dotsShape.graphics.moveTo(xH + 1, yH);
dotsShape.graphics.lineTo(gradRect.x, gradRect.y);
dotsShape.graphics.drawRect(xM-1, yM-1, 3, 3);
dotsShape.graphics.moveTo(xM + 1, yM);
dotsShape.graphics.lineTo(gradRect.x, gradRect.y + 0.5 * gradRect.height);
dotsShape.graphics.drawRect(xL-1, yL-1, 3, 3);
dotsShape.graphics.moveTo(xL + 1, yL);
dotsShape.graphics.lineTo(gradRect.x, gradRect.y + gradRect.height);
});
}
}
}
internal class WanderingDot
{
private static var _xMin:int = 0;
private static var _xMax:int = 255;
private static var _yMin:int = 0;
private static var _yMax:int = 255;
private var _vx:int;
private var _vy:int;
private var _px:int;
public function get x():int { return _px; }
public function set x(value:int):void
{
_px = value;
}
private var _py:int;
public function get y():int { return _py; }
public function set y(value:int):void
{
_py = value;
}
public function WanderingDot(x:int = 0, y:int = 0)
{
_vx = 1;
_vy = 1;
_px = x;
_py = y;
_validate();
}
private function _validate():void
{
if (_px < _xMin)
{
_px = _xMin;
_vx = 1;
}
else
if (_px > _xMax)
{
_px = _xMax;
_vx = -1;
}
if (_py < _yMin)
{
_py = _yMin;
_vy = 1;
}
else
if (_py > _yMax)
{
_py = _yMax;
_vy = -1;
}
}
public function update(n:uint):void
{
switch(n)
{
default:
case 0:
case 2:
break;
case 1:
if (_vx != 0 && _vy == 0)
{
_vy = 1;
}
else
if (_vx == 0 && _vy != 0)
{
_vx = 1;
}
else
{
_vx = 0;
}
break;
case 3:
if (_vx != 0 && _vy == 0)
{
_vy = -1;
}
else
if (_vx == 0 && _vy != 0)
{
_vx = -1;
}
else
{
_vy = 0;
}
break;
}
_px += _vx;
_py += _vy;
_validate();
}
}
internal class YCrCbColor
{
private var _y:uint;
public function get y():uint { return _y; }
public function set y(value:uint):void
{
_y = value;
}
private var _cr:uint;
public function get cr():uint { return _cr; }
public function set cr(value:uint):void
{
_cr = value;
}
private var _cb:uint;
public function get cb():uint { return _cb; }
public function set cb(value:uint):void
{
_cb = value;
}
public function YCrCbColor(y:uint = 0, cr:uint = 0, cb:uint = 0)
{
_y = y;
_cr = cr;
_cb = cb;
}
private static function makeWithRGB(r:int = 0, g:int = 0, b:int = 0):YCrCbColor
{
r &= 0xff;
g &= 0xff;
b &= 0xff;
var y :int = 77 * r + 150 * g + 29 * b;
var cr:int = (r << 7) -107 * g - 21 * b + 0x8000;
var cb:int = -43 * r - 85 * g + (b << 7) + 0x8000;
y >>= 8;
cr >>= 8;
cb >>= 8;
return new YCrCbColor(y, cr, cb);
}
public function toRGB():uint
{
var y :int = _y << 8;
var cr:int = _cr - 128;
var cb:int = _cb - 128;
var r:int = y + 359 * cr;
var g:int = y -183 * cr - 88 * cb;
var b:int = y + 453 * cb;
r = r < 0?0:r > 0xffff?0xff:(r >> 8);
g = g < 0?0:g > 0xffff?0xff:(g >> 8);
b = b < 0?0:b > 0xffff?0xff:(b >> 8);
return (r << 16) | (g << 8) | b;
}
//24bit分解能
//private static function makeWithRGB(r:int = 0, g:int = 0, b:int = 0):YCrCbColor
//{
//r &= 0xff;
//g &= 0xff;
//b &= 0xff;
//var y :int = 19595 * r + 38470 * g + 7471 * b;
//var cr:int = (r << 15) -27439 * g - 5329 * b + 0x800000;
//var cb:int = -11058 * r - 21710 * g + (b << 15) + 0x800000;
//y >>= 16;
//cr >>= 16;
//cb >>= 16;
//return new YCrCbColor(y, cr, cb);
//}
//
//public function toRGB():uint
//{
//var y :int = _y << 16;
//var cr:int = _cr - 128;
//var cb:int = _cb - 128;
//var r:int = y + 91882 * cr;
//var g:int = y -46802 * cr - 22553 * cb;
//var b:int = y + 116129 * cb;
//r = r < 0?0:r > 0xffffff?0xff:(r >> 16);
//g = g < 0?0:g > 0xffffff?0xff:(g >> 16);
//b = b < 0?0:b > 0xffffff?0xff:(b >> 16);
//return (r << 16) | (g << 8) | b;
//}
}