PDA

Ver la Versión Completa : Como obtengo los RGB's de un color más degradado que el que tengo


gluglu
15-05-2008, 18:39:41
Hola compañer@s !

Como puedo obtener a partir de un código de color dado (por ejemplo : $00FFF1BF) un tono más 'degradado' del mismo color ?

Se trata de que el usuario elija un color cualquiera, pero al yo mostrarlo en algunas partes del programa, este aparezca de forma degradado. Para ello el (los) componente(s) que utilizo tienen un valor Color y otro ColorTo.

Lo que tengo que calcular es dado un Color cualquiera, calcular y fijar el ColorTo de manera que quede bonito ! :rolleyes:

Gracias como siempre por vuestra ayuda.

Delphius
15-05-2008, 19:32:14
Hola gluglu,
¿A que te refieres con degradado? ¿Que sea más transparente? ¿O menos transparente?
Podrías hacer más o menos similar a lo que hice yo hace un tiempo cuando hice mi platilla de colores:

Elegí un color, a dicho color lo descompuse en los valores RGB.
En base al valor predominante disminuía o aumentaba los demás (y a éste) de modo que se mantenga la misma proporción.
Por ejemplo, si elijo el color (210,150,200) el que predomina es el rojo y le sigue de cerca el azul. Por tanto, si deseo un color más claro voy aumentando el valor hasta acercarme al 255 (blanco). Su aumento en x cantidad al rojo, los demás aumentan en la misma cantidad. Si deseo un color más oscuro, le resto.

Se puede incluso pensar en algo con porcentajes. Por ejemplo, si asumimos que el 255 viene a ser el máximo y que el mínimo es el 210. Tenemos que a lo largo de esos 45 el 100%, y lo demás es regla de 3 simple.
Por ejemplo, buscas un 30% de degradado.
Entonces: x = 30 x 45 / 100 = 13,5. Entonces debemos sumar 13 a los valores RGB. Entonces el color que obtenemos es (210 + 13, 150 + 13, 200 + 13) = (223,163,213).

¿Se entiende la idea?

He incluso, partiendo de ese color, podemos conseguir otros derivados que mantienen la misma elegancia y "tono" de modo que se obtiene la misma temática. Por ejemplo, en mi caso elejí el color Azul Cielo o SkyBlue. Y en base a él, obtuve el "Rojo Cielo", el "Verde Cielo". ¿Como se consegue? Muy fácil: Se rotan los valores de los canales menos predominantes. Siguiendo con el color del ejemplo: Del (210,150,200). conseguimos el (210,200,150). Y de allí incluso podemos conseguir variones promedios: se obtiene el promedio de los colores menos predominantes (210,(150+200)/2,(150+200)/2)) = (210,175,175). O Si deseas, obtener proporciones con respecto al valor predominante: (210,150+210/2,200) = (210,180,200), (210,150,200+210/2) = (210,150,205). Y la forma más sencilla para obtener el tono gris para la "temática" es tomar el promedio de los tres (187,187,187).

Espero que te sea de ayuda.

Saludos,

gluglu
15-05-2008, 19:44:44
Correcto .... eso es más o menos lo que busco. En mi caso particular es hacerlo más oscuro. Me vale tu idea. La probaré a ver qué tal.

Una pregunta adicional : dado el valor $ de un color (ejemplo : $00FFF1BF), como lo descompongo en RGB, y como lo vuelvo a convertir después a $ ?

Gracias por tus ideas. ;)

Edito : Ya lo encontré !! ColorToRGB y RGB !

Delphius
15-05-2008, 20:44:51
Me alegro que te sirva. Ese método que te pasé de sumar y restar en igual cantidad a cada canal es el más fácil. Pero a mi gusto estético le queda un poco desentonado. En realidad yo implemento una suma/resta independiente a cada canal. Ya que para mi, ofrece una proporción más pareja a la distribución del color y se consigue una gama de colores más adecuados para formar la "temática"

Mi método consiste en el siguiente:
por cada canal:
1. Obtengo un "delta". Este "delta" me indicará el incremento/decremento.
La fórmula que yo aplico es:
delta = (255 - ValorActual)/5. El 5 me indica que tan "espaciado" esté un color respecto al otro. Y limita por tanto la cantidad de colores que voy a obtener hasta llegar al más claro.
2. Entonces, el máximo valor que se puede alcanzar corresponderá a:
MaxValor = ValorActual + (delta * 4). Este 4, es aquel 5 - 1. Esto es a fines de no llegar al blanco, sino lo más cercano al blanco. Es decir que no llegará al valor 255.
En base al ejemplo, obtendría incrementos/decrementos de (9,21,11) respectivamente, con un espaciado de 5.

Si aplicaras este esquema, debes establecer un mínimo también, evitando caer al negro (0, cero). Este color mínimo debe ser aquel que mantenga el mismo predominante:
(210,150,200)
(201,129,189)
(192,108,178)
(183,87,167)
(174,66,156)
(165,45,145)
(156,24,134)
(147,3,123)

De modo que (147,3,123) es el color más oscuro que obtendrías. Y al igual, que el otro método puedes conseguir un degradado porcentual:

100% - 63 (210-147)
30% - x = 18,9. Aprox: 19

100% - 147 (150-3)
30% - x = 44,1. Aprox: 41

100% - 77 (200-123)
30% - x = 23,1. Aprox: 23

Entonces, el color a obtener es (210-19,150-41,200-23) = (191,109,177)

Puedes probar cuales de los dos métodos te resulta mejor estéticamente. A mi me gusta más este. Creo que mantiene mejor las tonalidades.
Podría pasarte un ejemplo de mi plantilla para que veas si estás interesado.

Saludos a todo color,

Neftali [Germán.Estévez]
16-05-2008, 10:44:22
Hace no muchos días contesté en los foros una pregunta similar.
A parte de lo que te comenta Delphius, que te ayudará a entender seguro cómo funciona el sistema de coloración y lo que debes hacer, yo te recomiendo que revises la unit GraphUtil que viene con Delphi. Algunas funciones que trae te pueden ser de utilidad:


function GetHighLightColor(const Color: TColor): TColor;
function GetShadowColor(const Color: TColor): TColor;
procedure ColorRGBToHLS(clrRGB: COLORREF; var Hue, Luminance, Saturation: Word);
function ColorHLSToRGB(Hue, Luminance, Saturation: Word): TColorRef;
function ColorAdjustLuma(clrRGB: TColorRef; n: Integer; fScale: BOOL): TColorRef;

gluglu
16-05-2008, 11:05:03
Ante todo, gracias a Delphius y Neftalí por responder.

Me sirvió la versión simple que explicó Delphius. Lo único que pretendía es dado un color determinado, provocar un cierto degradado de ese color a otro más oscuro y con la explicación de Delphius ha sido suficiente.

En cualquier caso he indagado en lo que dice Neftalí y al menos en BDS2006 no aparece esa unidad GraphUtil. Por lo que he podido 'googlear' parece que era de versiones anteriores como D6.

Saludos ;)

Neftali [Germán.Estévez]
16-05-2008, 11:41:49
En cualquier caso he indagado en lo que dice Neftalí y al menos en BDS2006 no aparece esa unidad GraphUtil. Por lo que he podido 'googlear' parece que era de versiones anteriores como D6.

En D2007 aparece la unit GraphUtil en el directorio \source\win32\vcl, así que me extraña que no esté en D2006.
¿Seguro que la has buscado bien? Sería muy raro que estuviera en D6 y D2007 y no en D2006.:confused:

gluglu
16-05-2008, 12:24:09
Tienes razón, Germán ! :o

Sí que está. Lo que me pasó es que después de tu post, inmediatamente fui a la ayuda de Delphi para ver la descripción de esas funciones, y en la ayuda ni me apereció ni me aparece nada acerca ni de las funciones descritas ni de la unidad GraphUtil.

... y fue por eso que precipitadamente deduje que en BDS 2006 no estaba dicha unidad. :o :o

Delphius
16-05-2008, 15:48:10
Hace no muchos días contesté en los foros una pregunta similar.
A parte de lo que te comenta Delphius, que te ayudará a entender seguro cómo funciona el sistema de coloración y lo que debes hacer, yo te recomiendo que revises la unit GraphUtil que viene con Delphi. Algunas funciones que trae te pueden ser de utilidad:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)function GetHighLightColor(const Color: TColor): TColor;
function GetShadowColor(const Color: TColor): TColor;
procedure ColorRGBToHLS(clrRGB: COLORREF; var Hue, Luminance, Saturation: Word);
function ColorHLSToRGB(Hue, Luminance, Saturation: Word): TColorRef;
function ColorAdjustLuma(clrRGB: TColorRef; n: Integer; fScale: BOOL): TColorRef;


Muchas gracias, esto es lo primero que llevo aprendido en el día. Desconocía absolutamente esta unidad.
Tengo que confesar que alguna que otra función de allí ha sido reescrita, y por tanto reinventada, por mi sabia ignorancia.

Muchas gracias amigo por mostrarme un poco más de luz, y quitarme un cacho más ignorancia.

Ahora me dispongo a ir al otro salón, antes de que suene el timbre. No vaya ser cosa de que llegue tarde a clases.;):)

Saludos,