Мне нужен способ вычислить более легкий шестнадцатеричный цвет (цвета) на основе обеспеченного. Я понимаю, что мог использовать преобразование цвета, но мне нужно фактическое значение для генерации градиента.
Вот кое-что из моих утилит Color. Похоже, makeGradient может быть вам полезен.
/**
* Return a gradient given a color.
*
* @param color Base color of the gradient.
* @param intensity Amount to shift secondary color.
* @return An array with a length of two colors.
*/
public static function makeGradient(color:uint, intensity:int = 20):Array
{
var c:Object = hexToRGB(color);
for (var key:String in c)
{
c[key] += intensity;
c[key] = Math.min(c[key], 255); // -- make sure below 255
c[key] = Math.max(c[key], 0); // -- make sure above 0
}
return [color, RGBToHex(c)];
}
/**
* Convert a uint (0x000000) to a color object.
*
* @param hex Color.
* @return Converted object {r:, g:, b:}
*/
public static function hexToRGB(hex:uint):Object
{
var c:Object = {};
c.a = hex >> 24 & 0xFF;
c.r = hex >> 16 & 0xFF;
c.g = hex >> 8 & 0xFF;
c.b = hex & 0xFF;
return c;
}
/**
* Convert a color object to uint octal (0x000000).
*
* @param c Color object {r:, g:, b:}.
* @return Converted color uint (0x000000).
*/
public static function RGBToHex(c:Object):uint
{
var ct:ColorTransform = new ColorTransform(0, 0, 0, 0, c.r, c.g, c.b, 100);
return ct.color as uint
}
Кроме того, не могу вспомнить, откуда я это взял, но эта статическая функция сгенерирует список гармонии с заданным цветом:
/**
* Convert RGB bits to a hexcode
*
* @param r Red bits
* @param g Green bits
* @param b Blue bits
* @return A color as a uint
*/
public static function convertToHex(r:uint, g:uint, b:uint):uint
{
var colorHexString:uint = (r << 16) | (g << 8) | b;
return colorHexString;
}
/**
* Get a series of complements of a given color.
*
* @param color Color to get harmonies for
* @param weight Threshold to apply to color harmonies, 0 - 255
*/
public static function getHarmonies(color:uint, weight:Number):Array
{
var red:uint = color >> 16;
var green:uint = (color ^ (red << 16)) >> 8;
var blue:uint = (color ^ (red << 16)) ^ (green << 8);
var colorHarmonyArray:Array = new Array();
//weight = red+green+blue/3;
colorHarmonyArray.push(convertToHex(red, green, weight));
colorHarmonyArray.push(convertToHex(red, weight, blue));
colorHarmonyArray.push(convertToHex(weight, green, blue));
colorHarmonyArray.push(convertToHex(red, weight, weight));
colorHarmonyArray.push(convertToHex(weight, green, weight));
colorHarmonyArray.push(convertToHex(weight, weight, blue));
return colorHarmonyArray;
}
Приходилось ли вам знакомиться с mx.utils.ColorUtil и методами adjustBrightness?
Вот функция, которую я написал для недавнего проекта, которая позволяет вам находить значение цвета между двумя другими на основе диапазона 0-1. Думаю, он вам подойдет
private function getBetweenColourByPercent(value:Number = 0.5 /* 0-1 */, highColor:uint = 0xFFFFFF, lowColor:uint = 0x000000):uint {
var r:uint = highColor >> 16;
var g:uint = highColor >> 8 & 0xFF;
var b:uint = highColor & 0xFF;
r += ((lowColor >> 16) - r) * value;
g += ((lowColor >> 8 & 0xFF) - g) * value;
b += ((lowColor & 0xFF) - b) * value;
return (r << 16 | g << 8 | b);
}
Самый точный способ сделать это - преобразовать значение RGB в HSL или HSV (Hue, Saturation, Luminance/Brightness), а затем отрегулировать значения насыщенности и яркости (оставив только оттенок). Затем конвертируйте обратно в RGB.
Когда вы пытаетесь выполнить математические вычисления непосредственно на значениях RGB, вы, как правило, получаете изменения оттенка.
Насыщенность - это степень чистоты цвета, значение 0,0 - серый, а значение 1,0 - чистый цвет.
Яркость и яркость - это не одно и то же, но они похожи. Они оба используются для перемещения значения в сторону черного или белого.
Поэтому, когда вы говорите "светлее", вы, вероятно, имеете в виду большее приближение к белому, но вы также можете иметь в виду большее приближение к серому (десатурированному). А возможно, и то, и другое.
Как только вы преобразовали значение RGB в оттенок, насыщенность и яркость, вы просто умножаете яркость на некоторое число > 1, чтобы сделать его ярче, или насыщенность на некоторое значение < 1, чтобы сделать его более серым. затем конвертируете обратно в RGB.
Я не знаю скрипт экшена, но вот псевдокод в стиле C для RGB->HSB и HSB->RGB.
unsigned int RGB;
double red = ((RGB >> 16) & 0xFF) / 255.0; // red value between 0.0 and 1.0
double green = ((RGB >> 8) & 0xFF) / 255.0;
double blue = ((RGB) & 0xFF) / 255.0);
double dmax = max(max(red, green) blue);
double dmin = min(min(red, green) blue);
double range = dmax - dmin;
double brite = dmax;
double sat = 0.0;
double hue = 0.0; // hue is always 0 when sat is 0
if (dmax != 0.0) sat = range / dmax;
if (sat != 0.0)
{
if (red == dmax)
hue = (green - blue) / range;
else if (green = dmax)
hue = 2.0 + (blue - red) / range;
else if (blue == dmax)
hue = 4.0 + (green - red) / range;
// it is conventional to convert hue to a value between 0 and 360.0 (a color circle)
hue = hue * 60;
if (hue < 0.0)
hue = hue + 360.0;
}
// result is now in hue, sat, & brite variables
double hue, sat, brite; // these are inputs
double red, green, blue;
if (sat == 0.0)
{
red = brite;
green = brite;
blue = brite;
}
else
{
if (hue == 360.0)
hue = 0;
int slice = (int)(hue / 60.0);
double hue_frac = (hue / 60.0) - slice;
double aa = brite * (1.0 - sat);
double bb = brite * (1.0 - sat * hue_frac);
double cc = brite * (1.0 - sat * (1.0 - hue_frac));
switch (slice)
{
case 0: red = brite; green = cc; blue = aa; break;
case 1: red = bb; green = brite; blue = aa; break;
case 2: red = aa; green = brite; blue = cc; break;
case 3: red = aa; green = bb; blue = brite; break;
case 4: red = cc; green = aa; blue = brite; break;
case 5: red = brite; green = aa; blue = bb; break;
default: red = 0.0; green = 0.0; blue = 0.0; break;
}
}
int ir = (int)(red * 255);
int ig = (int)(green * 255);
int ib = (int)(blue * 255);
// this is the result.
unsigned int RGB = (ir << 16) | (ig << 8) | ib;
Я перевел код c в AS3 и исправил несколько ошибок в коде. dmin вычислял max в функции rgb to hsb, а также при вычислении оттенка, когда синий является максимальным, он должен быть красным - зеленым, иначе голубой и пурпурный получаются наоборот.
private function RGBtoHSB(_rgb:uint):Object {
var red:Number = ((_rgb >> 16) & 0xFF) / 255.0;
var green:Number = ((_rgb >> 8) & 0xFF) / 255.0;
var blue:Number = ((_rgb) & 0xFF) / 255.0;
var dmax:Number = Math.max(Math.max(red, green), blue);
var dmin:Number = Math.min(Math.min(red, green), blue);
var range:Number = dmax - dmin;
var bright:Number = dmax;
var sat:Number = 0.0;
var hue:Number = 0.0;
if (dmax != 0.0) {
sat = range / dmax;
}
if (sat != 0.0) {
if (red == dmax) {
hue = (green - blue) / range;
}else if (green == dmax) {
hue = 2.0 + (blue - red) / range;
}else if (blue == dmax) {
hue = 4.0 + (red - green) / range;
}
hue = hue * 60;
if (hue < 0.0) {
hue = hue + 360.0;
}
}
return { "v":bright, "s":sat, "h":hue };
}
private function HSBtoRGB(_hue:Number, _sat:Number, _value:Number):uint {
var red:Number = 0.0;
var green:Number = 0.0;
var blue:Number = 0.0;
if (_sat == 0.0) {
red = _value;
green = _value;
blue = _value;
}else {
if (_hue == 360.0) {
_hue = 0;
}
var slice:int = _hue / 60.0;
var hue_frac:Number = (_hue / 60.0) - slice;
var aa:Number = _value * (1.0 - _sat);
var bb:Number = _value * (1.0 - _sat * hue_frac);
var cc:Number = _value * (1.0 - _sat * (1.0 - hue_frac));
switch(slice) {
case 0:
red = _value;
green = cc;
blue = aa;
break;
case 1:
red = bb;
green = _value;
blue = aa;
break;
case 2:
red = aa;
green = _value;
blue = cc;
break;
case 3:
red = aa;
green = bb;
blue = _value;
break;
case 4:
red = cc;
green = aa;
blue = _value;
break;
case 5:
red = _value;
green = aa;
blue = bb;
break;
default:
red = 0.0;
green = 0.0;
blue = 0.0;
break;
}
}
var ired:Number = red * 255.0;
var igreen:Number = green * 255.0;
var iblue:Number = blue * 255.0;
return ((ired << 16) | (igreen << 8) | (iblue));
}