PDA

Просмотр полной версии : СЛОЖНЫЕ ПРОСТЫЕ ЦВЕТА


teka
07.06.2006, 20:14
Кто подскажет как решить внешне крайне тривиальную задачу? Есть цвет (к примеру, 0xFF0000 - красный, то бишь). Как получить второй цвет, который будет более темным или более светлым по отношению к первому? (в примере: темно-красным или светло-красным). Что только не делал, какие только эксперименты не:o проводил, не помогает и все тут.

Nirth
07.06.2006, 20:20
Ваша тема не соответствует правилам данного раздела, ознакомьтесь пожалуйста с правилами форума (http://flasher.ru/forum/rules.php), а так же разделов (http://flasher.ru/forum/showthread.php?t=79864).
Тема перемещенна в раздел для "Для начинающих".

Usnul
07.06.2006, 20:34
ff0101 будет светлее, fe0000 будет темнее.

ЗЫ
пойди почитай про шестнадцатеричную систему исчисления сам, а?

teka
08.06.2006, 14:56
Пока с уважаемым Heilong-ом пытались менять offset-ы (ColorTransform). Практика показывает, что цвета "уплывают". Примеры с использованием класс Color прошу не предлагать. Устарело это дело все-таки.

iNils
08.06.2006, 15:14
Вернул тему назад в AS.

etc
08.06.2006, 15:46
teka, ColorTransform не так уж и сильно отличается от Color. Поэтому и переписать пример c Color на ColorTransform -- недолго.

teka
08.06.2006, 15:52
На самом деле я перегнул. Безусловно какой класс используешь - не суть важно. Да и вообще во флеше это делаешь или в какой иной проге - разницы нет. :-)

Iv
12.06.2006, 20:17
Пеннеровский tint (http://proto.layer51.com/d.aspx?f=143) очень кстати будет глянуть.

iNils
12.06.2006, 20:19
Пеннеровский tint (http://proto.layer51.com/d.aspx?f=143) очень кстати будет глянуть.
Причем тут это? Надо цвет RGB сначала перегнать в LAB, потом изменить значение L, и обратно перегнать RGB.

etc
12.06.2006, 20:31
Или скиннеровский ColorMatrix неплох :)

ну если есть время и желание ковырятся в формулах по переводу туда-сюда цвета, то да...

Iv
12.06.2006, 20:39
Причем тут это? Надо цвет RGB сначала перегнать в LAB, потом изменить значение L, и обратно перегнать RGB.
- что значит не при чем?! тинт к белому или черному даст нужный результат. Более того, использование именно tint я бы предпочел, даже если в данный момент не стоит задача tint как таковая, поскольку может понадобиться.
Если нужно взять цвет из безопасной поллитры, то можно перегнать (http://proto.layer51.com/d.aspx?f=94) результат.

iNils
12.06.2006, 20:42
Ив, мы о разных вещах говорим. Ты про манипуляции с цветом клипа, а я с самим цветом.
И вопрос на сколько я понял, был задан именно про сам цвет.

artcraft
12.06.2006, 21:02
class col {

static function toHSB(rgb:Number):Object{
var r = (rgb >> 16) & 0xFF;
var g = (rgb >> 8) & 0xFF;
var b = rgb & 0xFF;
var hsb = new Object();
hsb.b = Math.max(Math.max(r, g), b);
var min = Math.min(Math.min(r, g), b);
hsb.s = (hsb.b<=0) ? 0 : Math.round(100*(hsb.b-min)/hsb.b);
hsb.b = Math.round((hsb.b/255)*100);
hsb.h = 0;
if ((r == g) && (g == b)) {hsb.h = 0;}
else if (r>=g && g>=b) { hsb.h = 60*(g-b)/(r-b);}
else if (g>=r && r>=b) {hsb.h = 60+60*(g-r)/(g-b);}
else if (g>=b && b>=r) {hsb.h = 120+60*(b-r)/(g-r);}
else if (b>=g && g>=r) {hsb.h = 180+60*(b-g)/(b-r);}
else if (b>=r && r>=g) {hsb.h = 240+60*(r-g)/(b-g);}
else if (r>=b && b>=g) {hsb.h = 300+60*(r-b)/(r-g);}
else { hsb.h = 0; }
hsb.h = Math.round(hsb.h);
return hsb;
}


static function toRGB(hsb:Object):Number {
var r,g,b,rgb;
var h = Math.round(hsb.h);
var s = Math.round(hsb.s*255/100);
var v = Math.round(hsb.b*255/100);
if(s == 0) {
r = g = b = v;
} else {
var t1 = v;
var t2 = (255-s)*v/255;
var t3 = (t1-t2)*(h%60)/60;
if(h==360) h = 0;
if(h<60) {r=t1; b=t2; g=t2+t3}
else if(h<120) {g=t1; b=t2; r=t1-t3}
else if(h<180) {g=t1; r=t2; b=t2+t3}
else if(h<240) {b=t1; r=t2; g=t1-t3}
else if(h<300) {b=t1; g=t2; r=t2+t3}
else if(h<360) {r=t1; g=t2; b=t1-t3}
else {r=0; g=0; b=0}
}
//trace(r+' '+g+' '+b);
rgb = r << 16 | g << 8 | b;
return rgb;
}

static function modRGB(rgb:Number, s:Number, b:Number):Number {
var hsb:Object = col.toHSB(rgb);
hsb.s+=s;
if (hsb.s>100) {hsb.s=100}
if (hsb.s<0) {hsb.s=0}
hsb.b+=b;
if (hsb.b>100) {hsb.b=100}
if (hsb.b<0) {hsb.b=0}
return (col.toRGB(hsb));
}

}

как использовать:
var color1=0xEEEEEE;
var color2=col.modRGB(color1, 0, 10);//увеличивает яркость
var color3=col.modRGB(color1, 0, -10);//уменьшает яркость
(что происходит: цвет из ргб конвертируется в HSB, меняется яркость и цвет конвертируется обратно )

кроме того этот класс может менять насыщенность цвета, ну и конвертировать туда и обратно

etc
12.06.2006, 21:05
Кто автор кода? Судя по имени класса, название изменено.

iNils
12.06.2006, 21:19
Кто автор кода? Судя по имени класса, название изменено.
Похоже на Peter Hall.

artcraft
12.06.2006, 22:09
алгоритм конвертирования в HSB не помню где взял - немного поменял и добавил функцию modRGB

artcraft
12.06.2006, 22:11
Можно переименовать в "class artcraft.col" или "class cz.artcraft.color.utils"

etc
12.06.2006, 22:22
Отлично! Осталось привести его в порядок, чтобы не стыдно было использовать...

artcraft
12.06.2006, 22:33
а что там не так?

etc
12.06.2006, 22:48
Неверное имя класса. Имя с прописной буквы должно начинаться. Отсутствие типизации (местами есть), не объявлен тип метода. И это явно еще не все, это то, что можно увидеть на первый взгляд, без детального разбора.

Nirth
12.06.2006, 22:58
Нету комментариев в стиле JavaDoc, если не знаешь что такое то пишутся они так

/**
* Descriotion goes here
*
* @usage some example of usage
* @param paramName Type of param, decription
* @return type Type,decription
*/

iNils
12.06.2006, 23:47
Оригинал?
/*****************************************************
*
* Peter Hall 2002
* www.peterjoel.com
*
* HSB conversion methods for the Color object
*
* myCol.setHSB({H:hue, S:sat, B:bri})
* myCol.getHSB()
* - returns {H:hue, S:sat, B:bri}
*
* Static methods:
*
* Color.RGB_to_HSB(0xRRGGBB)
* - returns {H:hue, S:sat, B:bri}
* Color.HSB_to_RGB({H:hue, S:sat, B:bri})
* - returns 0xRRGGBB
*
* The colour-space conversion is based purely on
* my own interpretation and intuitive notion of the
* colour spaces. These methods may produce results
* which vary slightly from conversions carried out
* by different graphical software that you may be
* used to.
*
* If this script enables you or your company to make
* significant financial gain, you might like to make
* a contribution to show your appreciation. Please
* see my site for more information.
*
******************************************************/


Color.prototype.setHSB = function(colHSB){
var hue = (colHSB.H == null) ? 0 : (360+colHSB.H)%360;
var sat = (colHSB.S == null) ? 100 : colHSB.S;
var bri = (colHSB.B == null) ? 100 : colHSB.B;
this.setRGB(Color.HSB_to_RGB({H:hue,S:sat,B:bri}));
}

Color.prototype.getHSB = function(){
return Color.RGB_to_HSB(this.getRGB());
}

Color.RGB_to_HSB = function(colRGB){

var red = (colRGB&0xFF0000)>>16;
var gre = (colRGB&0x00FF00)>>8;
var blu = colRGB&0x0000FF;

var max = Math.max(red,Math.max(gre,blu));
var min = Math.min(red,Math.min(gre,blu));

var colHSB = {}
colHSB.B = Math.round(max*100/255);

if(max==min){ // if grey
colHSB.S = 0;
colHSB.H = 0;
}else{
colHSB.S = Math.round(100*(max-min)/max);
// find hue
var hue;
var tmpR = (max-red)/(max-min);
var tmpG = (max-gre)/(max-min);
var tmpB = (max-blu)/(max-min);
if(red==max){
hue = tmpB - tmpG;
}else if(gre==max){
hue = 2 + tmpR - tmpB;
}else if(blu==max){
hue = 4 + tmpG - tmpR;
}
colHSB.H = (Math.round(hue*60) + 360)%360;
}

return colHSB;

}

Color.HSB_to_RGB = function(colHSB){
var sat = colHSB.S;
var bri = colHSB.B;

var red, gre, blu;
// if grey don't bother doing any more
if(sat==0){
red = bri;
gre = bri;
blu = bri;
}else{

var hue = (colHSB.H+360)%360;
var hue2 = Math.floor(hue/60);

var dif = (hue%60)/60;
var mid1 = bri*(100-sat*dif)/100;
var mid2 = bri*(100-sat*(1-dif))/100;
var min = bri*(100-sat)/100;

if(hue2 == 0){
red = bri;
gre = mid2;
blu = min;
}else if(hue2 == 1){
red = mid1;
gre = bri;
blu = min;
}else if(hue2 == 2){
red = min;
gre = bri;
blu = mid2;
}else if(hue2 == 3){
red = min;
gre = mid1;
blu = bri;
}else if(hue2 == 4){
red = mid2;
gre = min;
blu = bri;
}else{
red = bri;
gre = min;
blu = mid1;
}
}
return (Math.round(red*255/100)<<16 | Math.round(gre*255/100) <<8 | Math.round(blu*255/100));
}

artcraft
13.06.2006, 00:27
нет - этот круче

bbexp
13.06.2006, 14:42
Не знаю, насколько нужны точные вычисления цвета, но просто затемнить или высветлить - по моему не так уж и сложно.
Когда то решал подобную задачу но в пределах RGB - без классов и прочего (извините, если не модно))



function deRGB(colour:Number):Object {
var rr:Number = (colour & 0xFF0000) >> 16;
var gg:Number = (colour & 0x00FF00) >> 8;
var bb:Number = colour & 0x0000FF;
return {R:rr,G:gg,B:bb}
}

var color:Number = 0xFF0000;

var colors:Object = deRGB(color);
var mr:Number = Math.floor(colors.R/3);
var mg:Number = Math.floor(colors.G/3);
var mb:Number = Math.floor(colors.B/3);
var darkerColor:Number = (mr << 16) + (mg << 8) + mb;





Конечно, коды уже приведенные здесь, безусловно круче и техничнее )) Но помоему решают несколько другие задачи.

artcraft
13.06.2006, 15:08
нет они решают именно те задачи, но и еще и дрегие заодно, например с этим классом совсем нетрудно "сдвинуть цвет по спектру" (поменять hue) или поменять насыщенность

teka
13.06.2006, 18:48
Причем тут это? Надо цвет RGB сначала перегнать в LAB, потом изменить значение L, и обратно перегнать RGB.
Смысл конвертации я понял, но как можно это сделать? Поискал по нету инфу, но толком ничего.

teka
13.06.2006, 18:50
Кривое-то решение я нашел на скорую руку. Задаю вторым цветом черный либо белый (в зависимости от оттенка второго цвета, который мне нужен) и выношу его "начало" подальше от заливаемой области. Получается эдакая имитация :-)

iNils
13.06.2006, 19:02
Смысл конвертации я понял, но как можно это сделать? Поискал по нету инфу, но толком ничего.
Чуть по позже время будет, я тебе постараюсь написать.