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。”