Pregunta

No conozco un título mejor, pero describiré el problema.

Una pieza de hardware que utilizamos tiene la capacidad de mostrar imágenes. Puede mostrar una imagen en blanco y negro con una resolución de 64 x 256.

El problema es el formato de la imagen que debemos enviar al dispositivo. No es un formato de mapa de bits estándar, sino que es simplemente una matriz de bytes que representan cada píxel de la imagen.

0 = negro, 1 = blanco.

Entonces, si tuviéramos una imagen con el tamaño: 4 x 4, la matriz de bytes podría ser algo como:

1000 0100 0010 0001

Y la imagen se vería como:

de mapa de bits http://www.mediafire.com/imgbnc.php/6ee6a28148d0170708cb10ec7ce6512e4g. jpg

El problema es que necesitamos crear esta imagen creando un mapa de bits monocromo en C # y luego conviértalo al formato de archivo comprendido por el dispositivo.

Por ejemplo, uno podría mostrar texto en el dispositivo. Para ello lo haría. Tienes que crear un mapa de bits y escribir texto en él:

var bitmap = new Bitmap(256, 64);

using (var graphics = Graphics.FromImage(bitmap))
{
    graphics.DrawString("Hello World", new Font("Courier", 10, FontStyle.Regular), new SolidBrush(Color.White), 1, 1);
}

Hay 2 problemas aquí:

  1. El mapa de bits generado no es monocromo
  2. El mapa de bits generado tiene un formato binario diferente

Así que necesito una manera de:

  1. Genere un mapa de bits monocromo en .NET
  2. Lea los colores de los píxeles individuales para cada píxel en el mapa de bits

Descubrí que puede establecer la profundidad de píxel en 16, 24 o 32 bits, pero no ha encontrado el monocromo y no tengo idea de cómo leer los datos de píxeles.

Las sugerencias son bienvenidas.

ACTUALIZACIÓN: no puedo usar Win32 PInvokes ... ¡tiene que ser neutral con respecto a la plataforma!

SEGUIMIENTO: El siguiente código me funciona ahora. (En caso de que alguien lo necesite)

private static byte[] GetLedBytes(Bitmap bitmap)
{
    int threshold = 127;
    int index = 0;
    int dimensions = bitmap.Height * bitmap.Width;

    BitArray bits = new BitArray(dimensions);

    //Vertically
    for (int y = 0; y < bitmap.Height; y++)
    {
        //Horizontally
        for (int x = 0; x < bitmap.Width; x++)
        {
            Color c = bitmap.GetPixel(x, y);
            int luminance = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
            bits[index] = (luminance > threshold);
            index++;
        }
    }

    byte[] data = new byte[dimensions / 8];
    bits.CopyTo(data, 0);
    return data;
}
¿Fue útil?

Solución

Calcularía la luminancia de cada píxel a y luego la compararía con algún valor de umbral.

y=0.3*R+0.59G*G+0.11*B

Supongamos que el valor umbral es 127:

const int threshold = 127;
Bitmap bm = { some source bitmap };

byte[,] buffer = new byte[64,256];

for(int y=0;y<bm.Height;y++)
{
  for(int x=0;x<bm.Width;x++)
  {
   Color c=source.GetPixel(x,y);
   int luminance = (int)(c.R*0.3 + c.G*0.59+ c.B*0.11);
   buffer[x,y] = (luminance  > 127) ? 1 : 0;
  }
}

Otros consejos

No sé C #. Posiblemente hay muchas maneras de hacerlo. Aquí es una manera simple.

  1. Cree una imagen de mapa de bits negra en blanco de tamaño igual al requisito de su dispositivo. Dibuje en él lo que quiera dibujar como texto, figuras, etc.

  2. Ahora ponga el umbral a la imagen, es decir, establezca el píxel de la imagen por debajo de un valor de intensidad en cero; p.ej. establecer todos los valores de intensidad > 0 a 1.

  3. Ahora convierta al formato requerido por su dispositivo. Cree una matriz de bytes del tamaño (64 * 256) / 8. Establezca los bits correspondientes en 1, donde los valores de píxel correspondientes en el mapa de bits anterior son 1, de lo contrario, restablézcalos a 0.

Editar: Paso 3. Usa operadores bitwise para establecer los bits.

¡No debes usar el método GetPixel de tu mapa de bits para convertir el mapa de bits completo de un formato a otro! Esto será ineficaz. En su lugar, debe usar el método LockBits para obtener acceso a una copia de la imagen buffer y convertirlo en formato deseado. No estoy completamente seguro de convertirlo a monocromo pero hay un valor de Format1bppIndexed en la enumeración de PixelFormat que puede ayudarlo.

Puede intentar proporcionar un formato de píxel en el constructor:

var bitmap = new Bitmap(256, 64, PixelFormat.Format1bppIndexed);

Cuando dibujé mapas de bits monocromos en otras plataformas que a veces tenía para desactivar el suavizado o el texto representado no se mostraría:

graphics.SmoothingMode=SmoothingMode.None;

YMMV.

Bitmap tiene un método GetPixel que puedes usar. Esto le permitirá dibujar en el mapa de bits y luego convertirlo al formato que necesita.

Los mapas de bits en formularios de Windows (es decir, a los que se accede a través de Graphics.FromImage) son de 24 bpp (¿quizás 32? Es demasiado pronto y, honestamente, lo olvido). No obstante, GetPixel devuelve un objeto Color, por lo que la profundidad de bits del mapa de bits es inmaterial. Le sugiero que escriba su código de esta manera:

MyBitmapFormat ToMyBitmap(Bitmap b)
{
    MyBitmapFormat mine = new MyBitmapFormat(b.Width, b.Height);

    for (int y=0; y < b.Height; y++) {
        for (int x=0; x < b.Width; x++) {
            mine.SetPixel(x, y, ColorIsBlackish(b.GetPixel(x, y)));
        }
    }
}

bool ColorIsBlackish(Color c)
{
    return Luminance(c) < 128; // 128 is midline
}

int Luminance(c)
{
    return (int)(0.299 * Color.Red + 0.587 * Color.Green + 0.114 * Color.Blue);
}

Este proceso se llama umbral simple. Es braindead, pero funcionará como un primer corte.

gracias por el código anterior. Estoy tratando de convertir una imagen monocromática en una matriz 2d donde 1-negro 0-blanco, sin embargo, estoy teniendo algunos problemas. Usé su código para cargar una imagen bmp de 8x8, y estoy enviando su contenido a un cuadro de texto usando

myGrid =GetLedBytes(myBmp);
     for (int x = 1; x < 8; x++)
     {
         textBox1.Text = textBox1.Text + Convert.ToString(myGrid[x])+ "  ";
     }

Sin embargo, obtengo esto como resultado en el cuadro de texto:

225  231  231  231  231  129  255  

¿Cómo lo obtengo para que sea 0 y 1?

Este capítulo tiene algún código que crea un mapa de bits mono. El ejemplo de SaveImage es el de interés.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top