白黒画像と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));
        }