Programación Específica > DirectX

 Color De Mascara

<< < (2/3) > >>

Amilius:
Creo que el problema es este:

(ushort)  ;)


--- Código: Text --- public Int32 ConvertirA16Bit(Int32 color)   {     return (Int32) ( ((color &#62;&#62; 8) & 0xF800) | ((color &#62;&#62; 5) & 0x07E0) | ((color &#62;&#62; 3) & 0x001F) );   }  
Una cosa más... esto depende de la forma de especificar el color en 24 o 32 bits... pero ¿No se intercambian el color rojo por el azul?

Editado: Faltaba la última máscara.  :rolleyes:

Ruben3d:

--- Citar ---Creo que el problema es este:

(ushort) 
--- Fin de la cita ---
Pudiera ser. En C++ así debería de funcionar (con sus tipos equivalentes) y el cast desecharía los bits más significativos y se quedaría con los menos: el color en 16 bits. En C# no sé cómo hacer eso.


--- Citar ---esto depende de la forma de especificar el color en 24 o 32 bits... pero ¿No se intercambian el color rojo por el azul?
--- Fin de la cita ---

Yo asumo que la entrada en un color de 32 bits es AARRGGBB y en uno de 24 es 00RRGGBB. Así, funciona para los dos casos. De todas formas, en algunos sitios ésto cambia. Por ejemplo, en los TGA se guarda el color en formato BGR en vez de RGB. Si la entrada es diferente, ya es cosa de JuanK adaptarla :D

Un saludo.

Ruben3d

JuanK:

--- Citar ---public Int32 ConvertirA16Bit(Int32 color)
  {
    return (Int32) ( ((color >> 8) & 0xF800) | ((color >> 5) & 0x07E0) | (color >> 3) );
  }

--- Fin de la cita ---


Mas o menos,  con eso se corrige el problema pero se corrige mal ya que el problema se genera porque se el valor resultante ocupa mas de 16 bits, asi que colorcar la funcion como tipo Int32 esconde el problema pero no lo soluciona.

el objetivo de la funcion es generar color de 16 bits asi que no deberia generarce nunca mas de 16 bit.


--- Citar ---Yo asumo que la entrada en un color de 32 bits es AARRGGBB y en uno de 24 es 00RRGGBB. Así, funciona para los dos casos. De todas formas, en algunos sitios ésto cambia. Por ejemplo, en los TGA se guarda el color en formato BGR en vez de RGB. Si la entrada es diferente, ya es cosa de JuanK adaptarla
--- Fin de la cita ---

Asi es , los datos no se estan leyendo del archivo sino directo de la memoria y por lo menos en lo que he visto en memoria de video todos son mapas de bits y el formato es como dice Ruben3D.

JuanK:
saludos
yo habia mejorado a esto:

--- Código: Text ---     public UInt16 ConvierteA16Bit(Int32 color)        {      byte uno, dos, tres;       /* Separar las componentes de byte       * para poder posteriormente calcular la proporcion       * independiente por cada componente de color.*/      uno = (byte)(color & 0x000000FF);      dos = (byte)((color & 0x0000FF00)&#62;&#62;8);      tres= (byte)((color & 0x00FF0000)&#62;&#62;16);       /* Calcular proporciones por regla de tres       * es decir ej.:       *  valor byte        max valor       *     uno               255 (0xFF, es decir maximo 8 bits prendidos)       *      ?                 31 (0x1F, es decir maximo 5 bits prendidos)       *         *  ? = uno * 31 /255 =&#62; ? = (0x1F*uno/0xFF)       * */      uno= (byte)(0x1F*uno/0xFF);      tres=(byte)(0x1F*tres/0xFF);      dos= (byte)(0x3F*dos/0xFF);       return (ushort)(  (uno|(dos &#60;&#60;5)) |                      ( (tres&#60;&#60;3 | dos&#62;&#62;3 ) ) &#60;&#60;8 );    } 
Pero no sabia como optimizar lo de las proporciones, en otro foro me dieron una solucion pero no entiendo muy bien la logica para llegar a ello, lo importante es que funciona.
Les pido ayuda por favor para ver si puedo entender mejor como se calcula lo de las proporciones utilizando  & y corrimientos en vez de multiplicacion y division?

aca esta como me quedo la adaptacion:

--- Código: Text ---     public UInt16 ConvierteA16Bit(Int32 color)        {      byte uno, dos, tres;       /* Separar las componentes de byte       * para poder posteriormente calcular la proporcion       * independiente por cada componente de color.*/      uno = (byte)(color & 0x000000FF);      dos = (byte)((color & 0x0000FF00)&#62;&#62;8);      tres= (byte)((color & 0x00FF0000)&#62;&#62;16);      return ( (ushort)( (((uno &#62;&#62; 3) & 0x1F) &#60;&#60; 11) | (((dos &#62;&#62; 2) & 0x3F) &#60;&#60; 5) | (((tres &#62;&#62; 3) & 0x1F) &#60;&#60; 0) ) );    }   

Ruben3d:

--- Citar ---
--- Código: Text ---    public UInt16 ConvierteA16Bit(Int32 color)       {      byte uno, dos, tres;       /* Separar las componentes de byte       * para poder posteriormente calcular la proporcion       * independiente por cada componente de color.*/      uno = (byte)(color & 0x000000FF);      dos = (byte)((color & 0x0000FF00)&#62;&#62;8);      tres= (byte)((color & 0x00FF0000)&#62;&#62;16);      return ( (ushort)( (((uno &#62;&#62; 3) & 0x1F) &#60;&#60; 11) | (((dos &#62;&#62; 2) & 0x3F) &#60;&#60; 5) | (((tres &#62;&#62; 3) & 0x1F) &#60;&#60; 0) ) );    } 
--- Fin de la cita ---

La verdad, no sé cómo funciona :P

uno, dos y tres guardan, respectivamente, las componentes azul, verde y roja, gracias a la máscara y al desplazamiento.

Llegados al return, el primer desplazamiento de bits se usa para rebajar su tamaño de 8 bits cada una a 5, 6 y 5 respectivamente.

A continuación aplica una máscara que me parece innecesaria, para poner a 0 los bits que no se usan (ya estaban a cero).

Por último, hace el desplazamiento que coloca cada componente en su posición final. Lo extraño es que parece hacerlo en formato BGR en vez de RGB, ya que 'uno', que es azul, lo pone en la posición del rojo. Y lo mismo pasa con el rojo, en la posición del azul. Por eso digo que no sé cómo funciona.

Por otro lado, prueba a ver si esta versión de la función que te di no arroja excepción:

--- Código: Text ---public UInt16 ConvierteA16Bit(Int32 color)   {     return (ushort) ( ( ((color &#62;&#62; 8) & 0xF800) | ((color &#62;&#62; 5) & 0x07E0) | (color &#62;&#62; 3) ) & 0x00FFFF);   }  
Lo que hago es aplicar una máscara que elimine los 8 bits de mayor peso, para ver si al tener un dato de 16 bits no se queja al devolverlo como ushort.

Un saludo.

Ruben3d

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa