C#中Byte[]数组、图像、BitmapSource互转

1.byte数组转图片

常用的Byte数组转图像的方法如下:

        public BitmapImage ByteArrayToBitmapImage(byte[] byteArray)
        {
            using (Stream stream = new MemoryStream(byteArray))
            {
                BitmapImage image = new BitmapImage();
                stream.Position = 0;
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.StreamSource = stream;
                image.EndInit();
                image.Freeze();
                return image;
            }
        }

这个方法只能够转本身带有图像格式信息byte数组,不然就会报错,比如用如下数组进行转图操作:

image.Source = ByteArrayToBitmapImage(new byte[500*500]);

报错信息如下:

COMException: 无法找不到组件。 (异常来自 HRESULT:0x88982F50)

这是因为上面给的数组只包含了单纯的色值信息,并不包含任何格式信息,在用该方法尝试转图的时候,处理函数不知道用什么类型的格式来操作。针对上面的数组,这个时候可以用下面的另一个方法进行转图操作:

public BitmapSource ByteArrayToBitmapSource(int width, int height, byte[] bytes)
{
    PixelFormat pixelFormat = PixelFormats.Gray8;
    int stride = width * pixelFormat.BitsPerPixel / 8;
    return BitmapSource.Create(width, height, 0, 0, 
        pixelFormat, null, bytes, stride);
}

此时得到的是一张500*500的全黑的图片。

2.图片转byte数组。方法较多,思路就是把图像读入到stream里面,将stream转换成Byte数组。

比如如下一种方式:

FileStream fs = new FileStream("test.jpg", FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] imgBytes = br.ReadBytes((int)fs.Length);

或者:

        public byte[] ImageToByteArray(Bitmap image)
        {
            MemoryStream ms = new MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            return ms.ToArray();
        }

3.Bitmap转成可以被wpf的Image控件使用的BitmapSource或BitmapImage

方法一:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

private void DemonstrateGetHbitmap()
{
    Bitmap bm = new Bitmap("Picture.jpg");
    IntPtr hBitmap = bm.GetHbitmap();

    var source= System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap,
            IntPtr.Zero, Int32Rect.Empty, 
            BitmapSizeOptions.FromEmptyOptions());

    DeleteObject(hBitmap);
}

该方法需要注意的是GetHbitmap方法其实从 Bitmap创建 GDI 位图对象,开辟的内存空间需要手动释放,否则会导致内存越来越大。

方法二:

private BitmapImage BitmapToBitmapImage(System.Drawing.Bitmap bitmap)
{
    MemoryStream ms = new MemoryStream();
    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    BitmapImage source = new BitmapImage();
    source.BeginInit();
    source.StreamSource = ms;
    source.EndInit();
    return source;
}

思路其实还是将图片写入到流,然后对流进行处理。

你可能感兴趣的:(c#,bitmapsource,bitmap,byte数组,wpf)