Recogiendo el guante… (pero poco a poco)

Hola!

Este artículo de phobeo me ha parecido una idea genial. Pequeños problemas para hacernos escurrir el coco e intentar hacerlo de la mejor manera posible 🙂

Así que, como indico en el título, voy a recoger el guante, pero poco a poco. Es decir, voy a exponer mi solución al segundo problema: Cómo darle la vuelta a los bits de un byte.

He decidido implementarlo usando recursividad. La idea es que el reverso es igual al reverso de la segunda mitad colocado en la primera mitad más el reverso de la primera mitad colocado en la segunda mitad. (Qué enrevesado suenaaaaa dicho con palabras… [:(] )

Bueno, un código vale más que mil palabras:

#include "stdafx.h"

#include "conio.h"

#define BYTE unsigned char

BYTE reverseChar(BYTE input, BYTE first, BYTE last);
BYTE reverse(BYTE input);

int _tmain(int argc, _TCHAR* argv[])
{
    BYTE input;
    BYTE resultado;
    int num = 0;
    int lookUp[255];

    for(int i=0; i<256; i++)
    {
        lookUp[ i ] = -1;
    }

    while(num != -1)
    {
        printf("Introduzca un numero entre 0 y 255 (-1 para terminar): ");
        scanf("%d", &num);

        if((num > -1) && (num < 256))
        {
            if(lookUp[num] == -1)
            {
                input = (BYTE) num;
                resultado = reverse(input);
                lookUp[input] = resultado;
            }
            else
            {
                resultado = (BYTE) lookUp[num];
            }

            printf("El byte dado la vuelta es: %d.n", resultado);
        }
    }

    return 0;
}

BYTE reverse(BYTE input)
{
    return reverseChar(input, 0, 7);
}

BYTE reverseChar(BYTE input, BYTE first, BYTE last)
{
    BYTE mask = 0x01;
    BYTE result = 0;
    BYTE delta;
    BYTE half1, half2;

    if(first == last - 1)
    {
        result = ((input & (mask << last)) >> 1) | ((input & (mask << first)) << 1);
    }
    else
    {
        delta = (last - first + 1) >> 1;
        
        half1 = reverseChar(input, first + delta, last);
        half2 = reverseChar(input, first, first + delta - 1);

        result = (half1 >> delta) | (half2 << delta);
    }

    return result;
}

Bueno, pues nada más por hoy. Dejo el código fuente en un ficherico zip adjunto.

Nostalgia: "El Universo Digital"

Hace ya unos cuantos años, antes de venir a Madrid, empecé a trabajar en Valladolid gracias a un buen amigo. En esa empresa tuve suerte de conocer a un «mega-crack» de la programación. Ése que era un Chuck Norris de la programación (como diría Pablo).


La persona en cuestión era Ciriaco García de Celis. Puede que el nombre no os suene a los más jóvenes, pero os puedo decir que él creó el programa 2M (un residente de MS-DOS gratuito que permitía formatear discos de 3 1/2 a 1.88Mb, y discos de 5 1/4 a 1.4Mb), entre otras muchas cosas. También diseñó un sistema de protección de aplicaciones basado en software que sólo se le puede ocurrir a alguien que conoce muy bien el hardware a bajo nivel, resistente al formateo de la máquina, por decir alguna otra perlita.


Pues bién, él fue el autor de un libro llamado «El Universo Digital», que tuve la suerte de comprarme en edición impresa. Hoy en día está disponible en internet, con una introducción que no aparece en el libro en papel. Ese libro era uno de los dos que podíamos llevar al examen de «Periféricos», una asignatura optativa muy interesante que se da en I. T. Sistemas, en el que aprendías a usar el hardware a bajo nivel – con C (qué jodío que era el puerto serie, oye). El otro era la Mega Biblia del PC de aquella época, el «PC Interno» (de Data Becker).


Con este pequeño recuerdo quería hacerle un breve homenaje, ya que, probablemente sin que él lo sepa, aprendí un montón de cosas de él.

Pintando imágenes semitransparentes con la clase Graphics

Hola!

Otro MicroArtículo. Esta vez vamos a ver cómo manipular los colores de una imagen utilizando la clase ColorMatrix. En concreto, el ejemplo que voy a mostrar es cómo pintar imágenes semitransparentes utilizando esta clase.

La clase ColorMatrix representa una matriz de transformación de colores. Los colores se representan mediante un vector (B,G,R,A,w) en su forma homogénea, en la que w siempre es igual a 1. (El resto del mundo lo representa como A,R,G,B,w). Por lo tanto, para transformar un color en otro, lo podemos multiplicar por una matriz 5×5.

Esta matriz contiene una serie de coeficientes que definen la transformación propiamente dicha. Si utilizamos la matriz identidad (una en la que todos los valores son 0 salvo la diagonal, cuyos valores son 1), modificando el valor que representa la opacidad – el canal alpha, o A en el vector) podremos dibujar una imagen semitransparente:

float[][] matrix = new float[][] { //B     G     R     A        w
                      new float[] {1.0f, 0.0f, 0.0f, 0.0f,     0.0f},  // B
                      new float[] {0.0f, 1.0f, 0.0f, 0.0f,     0.0f},  // G
                      new float[] {0.0f, 0.0f, 1.0f, 0.0f,     0.0f},  // R
                      new float[] {0.0f, 0.0f, 0.0f, opacidad, 0.0f},  // A
                      new float[] {0.0f, 0.0f, 0.0f, 0.0f,     1.0f}   // w
                                   };

En el caso en el que queramos aplicar una transformación a los colores, como puede ser por ejemplo el paso a escala de grises, donde el tono de gris viene dado por lo siguiente:

R' = G' = B' = 0.3 * R + 0.59 * G + 0.11 * B
A = 1

La matriz de transformación será la siguiente:

float[][] matrix = new float[][] { // B      G      R     A     w
                      new float[] {0.11f, 0.11f, 0.11f, 0.0f, 0.0f},  // B
                      new float[] {0.59f, 0.59f, 0.59f, 0.0f, 0.0f},  // G
                      new float[] { 0.3f,  0.3f,  0.3f, 0.0f, 0.0f},  // R
                      new float[] { 0.0f,  0.0f,  0.0f, 1.0f, 0.0f},  // A
                      new float[] { 0.0f,  0.0f,  0.0f, 0.0f, 1.0f}   // w
                                 };

Bueno… Pues nada más por hoy. Tenéis en el código adjunto un control que hace estas dos transformaciones, para que jugar un poco con ellas. Una aclaración: En el formulario del proyecto de prueba he puesto el color de fondo del control a Rojo, para que se vea más claramente que se está pintando semitransparente, ok? No es que esté dejando el canal rojo a 1 😉

Más sobre la limpieza de los TextBoxes. La palabra reservada as de C#.

Iba a contestar en un comentario a este post del blog de Juan Fco. Berrocal en el que se comenta cómo limpiar los textboxes de un formulario de una manera sencilla, pero voy a aprovechar para hacer un microartículo (pero micro micro) 😉

Aquí presento lo que me parece una versión un poco más depurada del tema que se trata en el post de forma implícita (manipulación de varios controles de una sola vez). Y debajo explico por qué lo hago así.

private void btnLimpiar_Click(object sender, EventArgs e)
{
  limpiarTextBoxes(this);
 
  // Y opcionalmente...
  this.textBox1.Focus();
}
 
private void limpiarTextBoxes(Control parent)
{
   TextBox t;
   
   //Limpiar de manera rapida
   foreach (Control c in parent.Controls)
   {
       t = c as TextBox;
 
       if (t != null)
       {
           t.Clear();
       }
 
       if (c.Controls.Count > 0)
       {
           limpiarTextBoxes(c);
       }
   }
}

La única diferencia es que en el bucle foreach de la rutina que limpia el texto del TextBox, se hace un casting del Control a TextBox usando la palabra reservada «as» de C#. Esto lo que hace es que si el control es un TextBox (o un derivado de él) obtiene una referencia de tipo TextBox, y si no, devuelve null. Lo bueno es que obtenemos una referencia tipada con la clase que queremos manipular.

Creo que es más claro hacer esto como ejemplo, porque si quisieras llamar a un método o usar una propiedad que sólo implementa la clase TextBox (por ejemplo la propiedad CharacterCasing) y no lo implementa la clase Control, utilizando este código sí que es posible, y con el anterior no…

Hala, pues ya está. ¿A que ha sido realmente micro?

Saludos!

EDITADO: He cambiado el código según la sugerencia de Alejandro Mezcua, para limpiar el TextBox utilizando el método Clear, en vez de Text = «». El motivo lo podéis ver en los comentarios 😉
 

Un par de artículos sobre SandCastle

Lo primero, disculparme por no haber publicado nada últimamente. Entre el acueducto y que tengo una situación complicada entre mis manos actualmente… No he podido sacar el tiempo necesario para leer ni escribir mucho 🙁 


Leo en The Code Project un par de artículos escritos por Eric Woodruff bastante interesantes sobre SandCastle.


El primero de ellos presenta una herramienta GUI para generar los ficheros de ayuda. El aspecto de esta herramienta es muy familiar, se nota que está claramente basado en nDoc. 😉


Sandcastle Help File Builder


El segundo artículo comenta cómo se puede personalizar la herramienta BuildAssembler para añadir características que puedas necesitar y que no proporcione directamente la herramienta, implementando componentes de generación (Build Components).


Creating Custom Build Components for Sandcastle