モノクロビットマップピクセルカラーの読み取り
質問
より良いタイトルはわかりませんが、問題について説明します。
使用しているハードウェアには、画像を表示する機能があります。 64 x 256の解像度で白黒画像を表示できます。
問題は、デバイスに送信する必要がある画像の形式です。 これは標準のビットマップ形式ではありませんが、代わりに単純な配列です 画像の各ピクセルを表すバイト。
0 =黒、1 =白。
したがって、サイズが4 x 4の画像がある場合、バイト配列は次のようになります。
1000 0100 0010 0001
そして、画像は次のようになります:
ビットマップhttp://www.mediafire.com/imgbnc.php/6ee6a28148d0170708cb10ec7ce6512e4g。 jpg
問題は、モノクロのビットマップを作成してこの画像を作成する必要があることです C#で、デバイスが理解できるファイル形式に変換します。
たとえば、デバイスにテキストを表示できます。そうするために彼は ビットマップを作成してテキストを書き込む必要があります:
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);
}
ここには2つの問題があります:
- 生成されたビットマップはモノクロではありません
- 生成されたビットマップは異なるバイナリ形式です
だから私はする方法が必要です:
- .NETでモノクロビットマップを生成
- ビットマップの各ピクセルの個々のピクセル色を読み取ります
ピクセル深度を16、24、または32ビットに設定できることがわかりましたが、モノクロが見つからず、ピクセルデータの読み取り方法がわかりません。
提案は大歓迎です。
更新: Win32 PInvokesを使用できません...プラットフォームに依存しない必要があります!
フォローアップ:次のコードが動作します。 (万が一必要な場合に備えて)
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;
}
解決
各ピクセルaの輝度を計算し、それをあるしきい値と比較します。
y=0.3*R+0.59G*G+0.11*B
しきい値は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;
}
}
他のヒント
C#がわかりません。おそらく多くの方法があります。簡単な方法を次に示します。
-
デバイスの要件に等しいサイズの空白の黒いビットマップイメージを作成します。テキスト、図形など、描きたいものを何でも描きます。
-
画像のしきい値を設定します。つまり、画像のピクセルを強度値以下に設定し、それ以外の場合は設定します。例えばすべての強度値を設定&gt; 0から1。
-
ここで、デバイスに必要な形式に変換します。サイズ(64 * 256)/ 8のバイト配列を作成します。以前のビットマップの対応するピクセル値が1である場合、対応するビットを1に設定します。それ以外の場合は、0にリセットします。
編集:ステップ3.ビットごとの演算子を使用してビットを設定します。
ビットマップ全体をある形式から別の形式に変換するために、ビットマップのGetPixelメソッドを使用しないでください!これは効果がありません。代わりに、 LockBits メソッドを使用して画像のコピーにアクセスする必要があります。バッファし、目的の形式に変換します。私はそれをモノクロに変換することについて完全に確信していませんが、あなたを助けるかもしれないPixelFormat列挙にFormat1bppIndexed値があります。
コンストラクタでピクセル形式を指定しようとする場合があります:
var bitmap = new Bitmap(256, 64, PixelFormat.Format1bppIndexed);
他のプラットフォームでモノクロビットマップを描画したとき、時々 アンチエイリアスを無効にすると、レンダリングされたテキストが表示されません:
graphics.SmoothingMode=SmoothingMode.None;
YMMV。
ビットマップにはGetPixelメソッドがありますあなたが使用できること。これにより、ビットマップに描画し、後で必要な形式に変換できます。
Windowsフォーム(つまり、Graphics.FromImageを介してアクセスされる)のビットマップは24 bpp(おそらく32ですか?早すぎて、正直に忘れています)。それでも、GetPixelはColorオブジェクトを返すため、ビットマップのビット深度は重要ではありません。次のようにコードを書くことをお勧めします。
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);
}
このプロセスは、単純なしきい値処理と呼ばれます。それは頭が痛いですが、最初のカットとして機能します。
上記のコードに感謝-私はモノクロ画像を1黒0白の2D配列に変換しようとしていますが、いくつかの問題が発生しています-あなたのコードを使用して8x8 bmp画像をロードし、使用して内容をテキストボックスに出力する
myGrid =GetLedBytes(myBmp);
for (int x = 1; x < 8; x++)
{
textBox1.Text = textBox1.Text + Convert.ToString(myGrid[x])+ " ";
}
ただし、結果としてテキストボックスに表示されます:
225 231 231 231 231 129 255
0と1になるように取得するにはどうすればよいですか?
このチャップには、モノビットマップを作成するコードがあります。 SaveImageサンプルは興味深いものです。