将BitmapImage转换为位图,反之亦然
我有C#中的BitmapImage。 我需要对图像进行操作。 例如灰度,在图像上添加文字等
我已经find了函数在灰度计算接受位图并返回位图的计算器。
所以我需要将BitmapImage转换为位图,做操作并转换回来。
我该怎么做? 这是最好的方法吗?
没有必要使用国外图书馆。
将BitmapImage转换为位图:
private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage) { // BitmapImage bitmapImage = new BitmapImage(new Uri("../Images/test.png", UriKind.Relative)); using(MemoryStream outStream = new MemoryStream()) { BitmapEncoder enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitmapImage)); enc.Save(outStream); System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream); return new Bitmap(bitmap); } }
将位图转换回BitmapImage:
[System.Runtime.InteropServices.DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); private BitmapImage Bitmap2BitmapImage(Bitmap bitmap) { IntPtr hBitmap = bitmap.GetHbitmap(); BitmapImage retval; try { retval = (BitmapImage)Imaging.CreateBitmapSourceFromHBitmap( hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } finally { DeleteObject(hBitmap); } return retval; }
这是将位图转换为BitmapImage的扩展方法。
public static BitmapImage ToBitmapImage(this Bitmap bitmap) { using (var memory = new MemoryStream()) { bitmap.Save(memory, ImageFormat.Png); memory.Position = 0; var bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.StreamSource = memory; bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.EndInit(); bitmapImage.Freeze(); return bitmapImage; } }
使用System.Windows.Interop; …
private BitmapImage Bitmap2BitmapImage(Bitmap bitmap) { BitmapSource i = Imaging.CreateBitmapSourceFromHBitmap( bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); return (BitmapImage)i; }
我刚刚尝试在我的代码中使用上述,我相信Bitmap2BitmapImage函数(也可能是另一个)有一个问题。
using (MemoryStream ms = new MemoryStream())
上述行是否导致stream被丢弃? 这意味着返回的BitmapImage会丢失其内容。
由于我是WPF新手,我不确定这是否是正确的技术解释,但是代码在我的应用程序中不起作用,直到我删除了使用指令。
如果你只需要从BitmapImage到Bitmap,这是很容易的,
private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage) { return new Bitmap(bitmapImage.StreamSource); }
这从System.Drawing.Bitmap转换为BitmapImage:
MemoryStream ms = new MemoryStream(); YOURBITMAP.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); BitmapImage image = new BitmapImage(); image.BeginInit(); ms.Seek(0, SeekOrigin.Begin); image.StreamSource = ms; image.EndInit();
这里是asynchronous版本。
public static Task<BitmapSource> ToBitmapSourceAsync(this Bitmap bitmap) { return Task.Run(() => { using (System.IO.MemoryStream memory = new System.IO.MemoryStream()) { bitmap.Save(memory, ImageFormat.Png); memory.Position = 0; BitmapImage bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.StreamSource = memory; bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.EndInit(); bitmapImage.Freeze(); return bitmapImage as BitmapSource; } }); }
感谢Guillermo Hernandez,我创build了一个可以工作的代码的变体。 我在这个代码中添加了命名空间以供参考。
System.Reflection.Assembly theAsm = Assembly.LoadFrom("My.dll"); // Get a stream to the embedded resource System.IO.Stream stream = theAsm.GetManifestResourceStream(@"picture.png"); // Here is the most important part: System.Windows.Media.Imaging.BitmapImage bmi = new BitmapImage(); bmi.BeginInit(); bmi.StreamSource = stream; bmi.EndInit();
你可以使用AForge.Net 。
具体来说,请参阅以下来自此AForge.Net入门文章的示例:
using AForge.Imaging.Filters; // Loading some file using (Bitmap SampleImage = (Bitmap)Image.FromFile("test.jpg")) { // We must convert it to grayscale because // the filter accepts 8 bpp grayscale images Grayscale GF = new Grayscale(0.2125, 0.7154, 0.0721); using (Bitmap GSampleImage = GF.Apply(SampleImage)) { // Saving the grayscale image, so we could see it later GSampleImage.SaveAsJpeg("testBW.jpg", 100); } }
HTH
- C#线程不会睡觉?
- Request.UrlReferrer为空?
- AppDomain和MarshalByRefObject的生命时间:如何避免RemotingException?
- 写入Windows应用程序事件日志,无需注册事件源
- C#或.NET中的程序集究竟是什么?
- 获取使用HttpWebRequest / HttpWebResponse进行的HTTP请求和响应以显示在Fiddler中
- 没有ListBox.SelectionMode =“None”,有没有另一种方法来禁用select列表框?
- 如何使用try catch进行exception处理是最佳实践
- 用户“DOMAIN \ MACHINENAME $”login失败