Преобразование BitmapImage в Bitmap и наоборот
У меня есть BitmapImage в С#. Мне нужно делать операции с изображением. Например, серая печать, добавление текста на изображение и т.д.
Я нашел функцию в stackoverflow для оттенков серого, которая принимает битмап и возвращает битмап.
Поэтому мне нужно преобразовать BitmapImage в Bitmap, выполнить операцию и преобразовать обратно.
Как я могу это сделать? Это лучший способ?
Ответы
Ответ 1
Нет необходимости использовать внешние библиотеки.
Преобразовать BitmapImage в Bitmap:
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);
}
}
Чтобы преобразовать 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;
}
Ответ 2
Здесь используется метод расширения для преобразования Bitmap в 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;
}
}
Ответ 3
с использованием System.Windows.Interop;
...
private BitmapImage Bitmap2BitmapImage(Bitmap bitmap)
{
BitmapSource i = Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
return (BitmapImage)i;
}
Ответ 4
Я только что пытался использовать выше в моем коде, и я считаю, что есть проблема с функцией Bitmap2BitmapImage (и, возможно, с другой).
using (MemoryStream ms = new MemoryStream())
Вызывается ли вышеприведенная строка в потоке? Это означает, что возвращенный BitmapImage теряет свой контент.
Как я новичок WPF, я не уверен, что это правильное техническое объяснение, но код не работал в моем приложении, пока я не удалю директиву using.
Ответ 5
Если вам просто нужно перейти из BitmapImage в Bitmap, это довольно просто,
private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
return new Bitmap(bitmapImage.StreamSource);
}
Ответ 6
Здесь асинхронная версия.
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;
}
});
}
Ответ 7
Это преобразование из 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();
Ответ 8
Спасибо Гильермо Эрнандес, я создал вариацию вашего кода, который работает. Я добавил пространства имен в этот код для справки.
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();
Ответ 9
Вы можете использовать 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);
}
}
НТН