Resumen Valor de RGB   (3 mensajes )

Normalmente los colores están en dos tipos de valores:
Hexadecimal: &HC0C0C0 para color gris
RGB: RGB(192,192,192) para el mismo color gris

Como ya sabrás, cada digito en hexadecimal representa cuatro bits. Si observas
con atención, al pasar el valor hexadecimal de 2 en 2 digitos a valor decimal
se obtiene el de cada color RGB (Red-Green-Blue) que lo compone. Por ejemplo C0 = 192. Es decir, cada byte (8 bits) representa el valor de cada color primario.
En el caso que tu señalas, el decimal 1362548, en valor hexadecimal sería &H14CA74, y pasandolo de byte en byte a decimal:
tercer byte (color azul) 14 = 20
segundo byte (color verde) CA = 202
primer byte (color rojo) 74 =116
El color sería RGB(116,202,20).

Pero si cada 8 bits definen un color RGB primario, en total serían 24 bits. Te
preguntarás ahora, puesto que estamos en Win32, que pasa con los 8 bits que faltan para completar los 32 bits que se supone que debería tener. Pues bien el cuarto byte, si es distinto de 0, es una constante o flag que indica que ese color es un color de sistema y no es un color RGB válido. Si es 0 sería un color RGB válido.

Santiago Jimeno (Madrid)
SJIMENOH28@smail1.ocenf.org

-----Mensaje original-----
De: Guy Gerbeau <ggerbeau@caparag.es>
Para: 'vb-esp@ccc.uba.ar' <vb-esp@ccc.uba.ar>
Fecha: miércoles 12 de mayo de 1999 19:08 p.m.
Asunto: vb-esp : Valor de RGB


>Amigos de la lista:
>Para saber el color RGB, lo leo y me da un valor grande, p. ej. 1362548.
>como puedo pasarlo a valor RGB(0-255,0-255,0-255)??
>Gracias ya por la ayuda.

A. David, Guy:

El manejo de colores en VB es relativamente sencillo teniendo unos pocos conceptos claros. Se puede asignar un color mediante la función RGB, mediante un valor (hexadecimal, decimal, constante de color) y mediante la funcion QBColor (que utiliza índices de paleta y los transforma en RGB por compatibilidad con versiones anteriores). Visual Basic hace bastante trabajo por nosotros con la asignación de colores y no es precisa demasiada
historia.

Posiblemente, para un uso corriente, no haga falta o sea excesiva toda la información que sigue. Pensaba que con lo explicado en mi anterior respuesta sería suficiente, pero al ampliarse la discusión he creido necesario desarrollarlo, añadiendo además mi propio código.

El código que nos mandas, A. David, es un magnífico ejemplo de manejo de cadenas y conversiones. Ya he podido observar tu dominio en tu página Web. Pero, efectivamente, en ese código existe como mínimo el error que señalas como posible, ya que Mid extrae para el rojo los dos primeros caracteres de la
cadena (pero Mid comienza por la izquierda), mientras que en un hexadecimal el rojo corresponde al byte menos significativo o inferior, que es el de la derecha. Con el azul ocurre al contrario, mientras el verde al ser el central siempre estaría bien. Yo cometí un error similar en mi respuesta a este tema, corregido después, al no tener en cuenta esto y que en la función RGB el orden
de los parámetros es rojo, verde, azul de izquierda a derecha.

Corregido lo anterior, funcionaría bastante bien si el color azul y verde fuesen distintos de 0. Pero si son 0, el número de caracteres de la cadena variará según haya o no colores verdes o azules especificados. Por ej. solo azul devolvería FF0000 (6 caracteres), solo verde FF00 (4) y solo rojo FF(2).
En el primer caso no hay problema, en los otros la función basada en Mid tambien fallaría. Corregir esto comprobando la longitud de la cadena es posible, pero haría el código más complejo y lento.

Pero hay otro problema, de cierta importancia, que tambien advertía en mi respuesta. El valor del color se obtiene en un Long. Si por cualquier motivo fuera un color de sistema, se rellenaría tambien el cuarto byte de ese Long (con la constante &H80, es decir, bit 31 del Long puesto a 1) y el código que
expones fallaría incluso con las dos correcciones que señalaba arriba, ya que Mid(strHex,1,2) no correspondería a un color sino a la constante de color de sistema, que además es de un tipo diferente (OLE_COLOR). Las siguientes extracciones con Mid darían igualmente valores falsos (cero en todos) excepto
en el primer byte, que no se extraería al ser los caracteres 7 y 8. Esto quizá pueda pareceros una aportación gratuita, para rizar el rizo, pero probad a obtener el valor de las propiedades predeterminadas de los formularios como BackColor o ForeColor (y bastantes propiedades más en VB, como se puede ver en
Constantes de Color en la Ayuda) y os darán valores de sistema (&H8000000F y &H80000012, respectivamente). Pasad este valor a una función GDI y nos estrellamos SEGURO. Esto es así aunque esas propiedades acepten valores RGB, ya que VB hace la conversión de forma oculta (con la API GetSysColor). Por último, solo añadir que se puede convertir un valor de sistema a valor RGB con la función API OleTranslateColor (de olepro32.dll).

Para obtener los valores RGB a partir de un Long:
'*************************En Declaraciones *************************
'Si es un módulo los UDT pueden ser Public. En Form y Clase, Private

Type BColor
    Rojo As Byte
    Verde As Byte
    Azul As Byte
    Sistema As Byte
End Type

Type LColor
    nColor As Long
End Type

'*************************En la función a usar*************************
Dim MixColor As LColor, RGBColor As BColor
MixColor.nColor = 1362548 'Se aceptan valores decimales
                                            'hexadecimales, Constantes de
                                            'Color ó el valor de una variable
                                            'Long pasada como parámetro
LSet RGBColor = MixColor 'Copia valores en memoria
'Aquí, en RGBColor, teneis sencillamente todos los valores separados por
'bytes, podeis utilizarlos con RGBColor. Rojo, etc, como necesiteis.

'Para prueba los muestro en un Msgbox
With RGBColor
            MsgBox "Rojo:" & .Rojo & " Verde:" & .Verde & _
            " Azul:" & .Azul & " Sistema:" & .Sistema
End With
'*************************************************************************
Si es un color RGB el valor de RGBColor.Sistema será 0. Y si es color de sistema el valor que se muestra (128) es la conversión decimal de la constante &H80. En este caso, se mostraría en RGBColor.Rojo el indicador que especifica el color de sistema. Si tan solo se necesita saber el tipo de color, se puede comprobar en código aparte con :

If ValorColor And &H80000000 then 'True si es de sistema
    'codigo para color de sistema
Else 'False si es RGB válido
    'código para color RGB
End If
'*************************************************************************


Santiago Jimeno (Madrid)
SJIMENOH28@smail1.ocenf.org

> -----Mensaje original-----
> De: Guy Gerbeau <ggerbeau@caparag.es>
> Para: 'vb-esp@ccc.uba.ar' <vb-esp@ccc.uba.ar>
> Fecha: Miércoles 12 de Mayo de 1999 11:14 AM
> Asunto: vb-esp : Valor de RGB
>
>
> >Amigos de la lista:
> >Para saber el color RGB, lo leo y me da un valor grande, p. ej. 1362548.
> >como puedo pasarlo a valor RGB(0-255,0-255,0-255)??
> >Gracias ya por la ayuda.


Podrías hacer algo como esto:

********************************************************************
' Var
Dim bytRojo As Byte
Dim bytVerde As Byte
Dim bytAzul As Byte
Dim strHex As String

' Supongamos que tenemos el número decimal en la
' variable lngColor.
strHex = Hex(lngColor)
bytRojo = Val("&H" & Mid(strHex,1,2)) ' Este es el rojo
bytVerde = Val("&H" & Mid(strHex,3,2)) ' Este es el verde
bytAzul = Val("&H" & Mid(strHex,5,2)) ' Este es el azul
**********************************************************************

Así obtendrías la saturación de cada color en el número decimal que te den.

No lo he probado, pero lo más que podría pasar es que esté incorrecta la obtención del rojo y la del azul, de manera que tuvieses que alternarla:
donde aquí obtengo el rojo, obtener el azul, y viceversa.

+---¡Saludos desde México!--+
| .+'~~'+. |
| * Tron * David.BAS |
| `+,__,+' |
+---------------------------+
 http://www.spin.com.mx/~adgarza
adgarza@spin.com.mx



Resumen Resumen

Visual Basic Página de Visual Basic

Página principal Página principal

www.jrubi.com