如何在 C# 中将位图转换为一维字节数组,反之亦然?

How can I convert a Bitmap to a 1D byte array and vice versa in C#?

我写了下面的方法,

public static byte[] BitmapToByteArray(Bitmap image)
        {
            byte[] returns = null;
            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                BitmapData bitmapData = image.LockBits(
                                                new Rectangle(0, 0, image.Width, image.Height),
                                                ImageLockMode.ReadWrite,
                                                image.PixelFormat);
                int noOfPixels = image.Width * image.Height;
                int colorDepth = Bitmap.GetPixelFormatSize(image.PixelFormat);
                int step = colorDepth / 8;
                byte[] bytes = new byte[noOfPixels * step];
                IntPtr address = bitmapData.Scan0;
                Marshal.Copy(address, bytes, 0, bytes.Length);
                ////////////////////////////////////////////////
                ///
                returns = (byte[])bytes.Clone();
                ///
                ////////////////////////////////////////////////
                Marshal.Copy(bytes, 0, address, bytes.Length);
                image.UnlockBits(bitmapData);
            }
            else
            {
                throw new Exception("8bpp indexed image required");
            }
            return returns;
        }

并且,

public static Bitmap ByteArrayToBitmap(byte[] bytes, int width, int height, PixelFormat pixelFormat)
        {
            Bitmap bitmap = new Bitmap(width, height, pixelFormat);
            BitmapData bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
            int colorDepth = Bitmap.GetPixelFormatSize(pixelFormat);
            int noOfChannels = colorDepth / 8;
            IntPtr address = bitmapData.Scan0;
            //////////////////////////////////////////////////////////////
            //
            Marshal.Copy(bytes, 0, address, width * height * noOfChannels);
            //
            //////////////////////////////////////////////////////////////
            bitmap.UnlockBits(bitmapData);

            return bitmap;
        }

它们似乎不起作用,

您觉得问题出在哪里?

N.B.

驱动程序,

public class MainClass
{
    public static void Main(string [] args)
    {
        Bitmap inputBmp = (Bitmap)Bitmap.FromFile(@"cameraman.gif");

        byte[] bytes = Converter.BitmapToByteArray(inputBmp);//byte[65536]

        Bitmap outputBmp = Converter.ByteArrayToBitmap(bytes, inputBmp.Width, inputBmp.Height, PixelFormat.Format8bppIndexed);

        PictureDisplayForm f = new PictureDisplayForm(inputBmp, outputBmp);
        f.ShowDialog();
    }
}

好的。

我已经解决了

public static byte[] BitmapToByteArray(Bitmap image)
        {
            byte[] returns = null;
            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                BitmapData bitmapData = image.LockBits(
                                                new Rectangle(0, 0, image.Width, image.Height),
                                                ImageLockMode.ReadWrite,
                                                image.PixelFormat);
                int noOfPixels = image.Width * image.Height;
                int colorDepth = Bitmap.GetPixelFormatSize(image.PixelFormat);
                int step = colorDepth / 8;
                byte[] bytes = new byte[noOfPixels * step];
                IntPtr address = bitmapData.Scan0;
                Marshal.Copy(address, bytes, 0, bytes.Length);
                ////////////////////////////////////////////////
                ///
                returns = (byte[])bytes.Clone();
                ///
                ////////////////////////////////////////////////
                Marshal.Copy(bytes, 0, address, bytes.Length);
                image.UnlockBits(bitmapData);
            }
            else
            {
                throw new Exception("8bpp indexed image required");
            }
            return returns;
        }

        public static Bitmap ByteArray1dToBitmap(byte[] bytes, int width, int height)
        {
            PixelFormat pixelFormat = PixelFormat.Format8bppIndexed;
            Bitmap bitmap = new Bitmap(width, height, pixelFormat);

            // Set the palette for gray shades
            ColorPalette pal = bitmap.Palette;
            for (int i = 0; i < pal.Entries.Length; i++)
            {
                pal.Entries[i] = Color.FromArgb(i, i, i);
            }
            bitmap.Palette = pal;

            BitmapData bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, pixelFormat);
            int colorDepth = Bitmap.GetPixelFormatSize(pixelFormat);
            int noOfChannels = colorDepth / 8;

            unsafe
            {
                byte* address = (byte*)bitmapData.Scan0;
                int area = width * height;
                int size = area * noOfChannels;
                for (int i = 0; i < area; i++)
                {
                    address[i] = bytes[i];//262144 bytes
                }
            }

            //////////////////////////////////////////////////////////////
            bitmap.UnlockBits(bitmapData);

            return bitmap;
        }