白黒画像とbyte配列の変換
白黒2値なので、1byteに8ピクセル入る。元が1ピクセルRGBで3byteだったので24倍圧縮
C#だとbyte型の各bitに直接アクセスできなくて辛い。ひどいことになってしまった。どうみてもほとんど差がないコードでも、ちょっと変えるだけで「byteをintにキャストできません」というエラーがでてしまい、これに落ち着いた。処理は遅いのでそのうちなんとかする
public const int Width = 60; // サイズは固定 public const int Height = 40; public static byte[] BitmapToByteArray(Bitmap bmp) { byte[] bytes = new byte[Width * Height / 8]; try { Bitmap bmpResized = new Bitmap(bmp, Width, Height); for (int i = 0; i < Width * Height; i++) { int x = i % Width; int y = i / Width; Color pix = bmpResized.GetPixel(x, y); if (pix.R > 0 || pix.G > 0 || pix.B > 0) // 完全に黒でないものは全部白と見なす { bytes[i / 8] &= (byte)~(0x01 << (i % 8)); } else { bytes[i / 8] |= (byte)(0x01 << (i % 8)); } } return bytes; } catch (Exception ex) { throw ex; } } public static Bitmap ByteArrayToBitmap(byte[] bytes) { try { Bitmap bmp = new Bitmap(Width, Height); for (int i = 0; i < Width * Height; i++) { int x = i % Width; int y = i / Width; if ((bytes[i / 8] & (0x01 << i % 8)) > 0) bmp.SetPixel(x, y, Color.Black); else bmp.SetPixel(x, y, Color.White); } return bmp; } catch (Exception ex) { throw ex; } }
さらにBase64 Encodeするとネットワークに流しやすい
public static String Encode(Bitmap bmp) { return Convert.ToBase64String(BitmapToByteArray(bmp)); } public static Bitmap Decode(String encoded) { return ByteArrayToBitmap(Convert.FromBase64String(encoded)); }