如何在 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;
}
我写了下面的方法,
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;
}