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;
   var image = BitmapSource.Create(width, height, 0, 0, 
   pixelFormat, null, bytes, stride);
   image.Freeze();
   return image;
}

此时得到的是一张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;
}

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

注:BitmapSource或BitmapImage如果要被ui的image控件直接绑定使用,在异步操作情况下,必须调用Freeze方法,否则就会报错:

System.ArgumentException:“必须在与 DependencyObject 相同的 Thread 上创建 DependencySource。”

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值