Leitura cores de pixel bitmap monocromáticas
Pergunta
Eu não sei um título melhor, mas vou descrever o problema.
Um pedaço de uso que hardware tem a capacidade de exibir imagens. Ele pode exibir uma imagem em preto e branco com uma resolução de 64 x 256.
O problema é o formato da imagem que temos de enviar para o dispositivo. Não é um formato bitmap padrão, mas em vez disso, é simplesmente um conjunto de bytes representando cada pixel da imagem.
0 = preto, 1 = branco.
Então, se tivéssemos uma imagem com o tamanho: 4 x 4 a matriz de bytes pode ser algo como:
1000 0100 0010 0001
E a imagem seria parecido com:
Bitmap http://www.mediafire.com/imgbnc.php/6ee6a28148d0170708cb10ec7ce6512e4g. jpg
O problema é que nós precisamos para criar esta imagem criando um bitmap monocromático em C # e, em seguida, convertê-lo para o formato de arquivo entendido pelo dispositivo.
Por exemplo, pode-se para exibir o texto no dispositivo. A fim de fazê-lo que ele faria tem que criar um bitmap e texto de escrita para ele:
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);
}
Existem 2 problemas aqui:
- O bitmap gerado não é monocromático
- O bitmap gerado tem um formato binário diferente
Então eu preciso de uma maneira de:
- Gerar um bitmap monocromático no .NET
- Leia as cores de pixel individuais para cada pixel no bitmap
Eu descobri que você pode definir a profundidade do pixel para 16, 24 ou 32 bits, mas não encontraram monocromática e não tenho idéia de como ler os dados de pixel.
As sugestões são bem-vindos.
UPDATE: Não consigo utilizar Win32 PInvokes ... tem que ser plataforma neutra
!Acompanhamento: As seguintes obras de código para mim agora. (Apenas no caso de alguém precisa dele)
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;
}
Solução
Eu calcular a luminosidade de cada pixel um, em seguida, compará-lo com algum valor limiar.
y=0.3*R+0.59G*G+0.11*B
Say o valor limite é de 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;
}
}
Outras dicas
Eu não sei C #. Há possivelmente muitas maneiras de fazê-lo. Aqui está uma maneira simples.
-
Criar uma imagem bitmap preto em branco de tamanho igual com sua exigência dispositivo. Desenhar nele o que você deseja desenhar como texto, números etc.
-
limiar Agora a imagem ou seja, definir o pixel da imagem abaixo um valor de intensidade de zero ou configure-o para. por exemplo. definir todos os valores de intensidade> 0 a 1.
-
Agora converter para o formato exigido pelo dispositivo. Criar uma matriz de bytes do tamanho (64 * 256) / 8. Definir os bits correspondentes a 1, onde os valores dos pixels correspondentes em bitmap anteriormente são 1, o mais redefini-las a 0.
Edit:. Passo 3. Use operadores bit a bit para definir os bits
Você não deve usar o método GetPixel do seu bitmap para converter toda bitmap de um formato para outro! Este será ineficaz. Em vez disso você deve usar LockBits método para obter acesso a uma cópia da imagem tampão e convertê-lo para o formato desejado. Eu não estou completamente certo sobre convertê-lo para o modo monocromático, mas há um valor Format1bppIndexed em PixelFormat enumeração que pode ajudá-lo.
Pode tentar fornecer um PixelFormat no construtor:
var bitmap = new Bitmap(256, 64, PixelFormat.Format1bppIndexed);
Quando eu tinha desenhar bitmaps monocromáticos em outras plataformas eu às vezes tinha Para desativar suavização ou o texto processado não iria aparecer:
graphics.SmoothingMode=SmoothingMode.None;
YMMV.
Bitmap tem um método GetPixel que você pode usar. Isso permitirá que você desenhar no bitmap e depois convertê-lo para o formato que você precisa.
Os mapas de bits em formulários do Windows (ou seja, acessado através Graphics.FromImage) são 24 bpp (talvez 32? É muito cedo e eu honestamente esquecer). No entanto, GetPixel retorna um objeto de cor, de modo a profundidade do bitmap bit é imaterial. Eu sugiro que você escrever seu código como este:
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 processo é chamado de limite simples. É de braindead, mas vai funcionar como um primeiro corte.
agradecimentos para o código acima - Eu estou tentando converter uma imagem monocromática em uma matriz 2d, onde 1-preta 0-branco no entanto eu estou tendo alguns problemas - eu usei o código para carregar uma imagem bmp 8x8, e am a saída de seu conteúdo para uma caixa de texto usando
myGrid =GetLedBytes(myBmp);
for (int x = 1; x < 8; x++)
{
textBox1.Text = textBox1.Text + Convert.ToString(myGrid[x])+ " ";
}
No entanto eu recebo isso como um resultado na caixa de texto:
225 231 231 231 231 129 255
como faço para obtê-lo por isso é 0 e 1 de?
Esta rachadura tem algum código que cria um mono bitmap. A amostra SaveImage é o de interesse.