Domanda

Non conosco un titolo migliore, ma descriverò il problema.

Un componente hardware che utilizziamo ha la capacità di visualizzare immagini. Può visualizzare un'immagine in bianco e nero con una risoluzione di 64 x 256.

Il problema è il formato dell'immagine che dobbiamo inviare al dispositivo. Non è un formato bitmap standard, ma è semplicemente un array di byte che rappresentano ciascun pixel dell'immagine.

0 = nero, 1 = bianco.

Quindi, se avessimo un'immagine con le dimensioni: 4 x 4, l'array di byte potrebbe assomigliare a:

1000 0100 0010 0001

E l'immagine sarebbe simile:

Bitmap http://www.mediafire.com/imgbnc.php/6ee6a28148d0170708cb10g7ce65 jpg

Il problema è che dobbiamo creare questa immagine creando una bitmap monocromatica in C # e poi convertilo nel formato file compreso dal dispositivo.

Ad esempio, si potrebbe visualizzare il testo sul dispositivo. Per farlo, lo farebbe devi creare una bitmap e scrivere del testo su di essa:

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);
}

Ci sono 2 problemi qui:

  1. La bitmap generata non è monocromatica
  2. La bitmap generata ha un formato binario diverso

Quindi ho bisogno di un modo per:

  1. Genera una bitmap monocromatica in .NET
  2. Leggi i singoli colori dei pixel per ciascun pixel nella bitmap

Ho scoperto che è possibile impostare la profondità del pixel su 16, 24 o 32 bit, ma non ho trovato il bianco e nero e non ho idea di come leggere i dati dei pixel.

I suggerimenti sono benvenuti.

AGGIORNAMENTO: Non riesco a usare Win32 PInvokes ... deve essere neutrale rispetto alla piattaforma!

SEGUI SU: Il seguente codice funziona ora per me. (Nel caso in cui qualcuno ne abbia bisogno)

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;
}
È stato utile?

Soluzione

Calcolerei la luminanza di ciascun pixel e lo confronterei con un valore di soglia.

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

Dire che il valore di soglia è 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;
  }
}

Altri suggerimenti

Non conosco C #. Probabilmente ci sono molti modi per farlo. Ecco un modo semplice.

  1. Crea un'immagine bitmap nera vuota di dimensioni pari al requisito del tuo dispositivo. Disegna su quello che vuoi disegnare come testo, figure ecc.

  2. Ora soglie l'immagine, ovvero imposta il pixel dell'immagine sotto un valore di intensità su zero, altrimenti impostalo su. per esempio. imposta tutti i valori di intensità > Da 0 a 1.

  3. Ora converti nel formato richiesto dal tuo dispositivo. Crea un array di byte delle dimensioni (64 * 256) / 8. Impostare i bit corrispondenti su 1 dove i valori dei pixel corrispondenti nella bitmap precedente sono 1, altrimenti reimpostarli su 0.

Modifica: passaggio 3. Utilizzare gli operatori bit a bit per impostare i bit.

Non dovresti usare il metodo GetPixel della tua bitmap per convertire l'intera bitmap da un formato all'altro! Questo sarà inefficace. Dovresti invece utilizzare il metodo LockBits per accedere a una copia dell'immagine buffer e convertirlo nel formato desiderato. Non sono del tutto sicuro di convertirlo in bianco e nero, ma c'è un valore Format1bppIndexed nell'enumerazione PixelFormat che può aiutarti.

Puoi provare a fornire un formato pixel nel costruttore:

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

Quando disegnavo bitmap monocromatiche su altre piattaforme, a volte lo avevo per disabilitare l'antialias o il testo renderizzato non verrebbe visualizzato:

graphics.SmoothingMode=SmoothingMode.None;

YMMV.

Bitmap ha un metodo GetPixel che puoi usare. Questo ti permetterà di disegnare su Bitmap e successivamente convertirlo nel formato che ti serve.

Le bitmap nei moduli di Windows (ovvero, accessibili tramite Graphics.FromImage) sono 24 bpp (forse 32? È troppo presto e lo dimentico onestamente). Tuttavia, GetPixel restituisce un oggetto Color, quindi la profondità di bit della bitmap è irrilevante. Ti suggerisco di scrivere il tuo codice in questo modo:

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);
}

Questo processo è chiamato soglia semplice. È braindead, ma funzionerà come primo taglio.

grazie per il codice sopra - Sto provando a convertire un'immagine monocromatica in un array 2d dove 1-nero 0-bianco comunque ho qualche problema - Ho usato il tuo codice per caricare un'immagine 8x8 bmp, e sono inoltrando il suo contenuto in una casella di testo usando

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

tuttavia ottengo questo come risultato nella casella di testo:

225  231  231  231  231  129  255  

come posso ottenerlo in modo che sia 0 e 1?

Questo tipo ha del codice che crea una bitmap mono. L'esempio SaveImage è quello di interesse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top