Есть ли хороший способ конвертировать между BitmapSource и Bitmap?



Насколько я могу судить, единственный способ преобразовать BitmapSource в Bitmap-это использовать небезопасный код... Вот так (из блога Lesters WPF):



myBitmapSource.CopyPixels(bits, stride, 0);

unsafe
{
fixed (byte* pBits = bits)
{
IntPtr ptr = new IntPtr(pBits);

System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(
width,
height,
stride,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb,ptr);

return bitmap;
}
}


Чтобы сделать обратное:



System.Windows.Media.Imaging.BitmapSource bitmapSource =
System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());


Есть ли более простой способ в рамках? И по какой причине его там нет (если его нет)? Я бы сказал, что он вполне пригоден для использования.



Причина, по которой мне это нужно, заключается в том, что я использую AForge для выполнения определенных операций с изображениями в приложении WPF. WPF хочет показать BitmapSource/ImageSource, но AForge работает на растровых изображениях.

695   6  

6 ответов:

Можно обойтись без использования небезопасного кода с помощью Bitmap.LockBits и скопировать пиксели из BitmapSource прямо в Bitmap

Bitmap GetBitmap(BitmapSource source) {
  Bitmap bmp = new Bitmap(
    source.PixelWidth,
    source.PixelHeight,
    PixelFormat.Format32bppPArgb);
  BitmapData data = bmp.LockBits(
    new Rectangle(Point.Empty, bmp.Size),
    ImageLockMode.WriteOnly,
    PixelFormat.Format32bppPArgb);
  source.CopyPixels(
    Int32Rect.Empty,
    data.Scan0,
    data.Height * data.Stride,
    data.Stride);
  bmp.UnlockBits(data);
  return bmp;
}

Вы можете просто использовать эти два метода:

public static BitmapSource ConvertBitmap(Bitmap source)
{
    return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                  source.GetHbitmap(),
                  IntPtr.Zero,
                  Int32Rect.Empty,
                  BitmapSizeOptions.FromEmptyOptions());
}

public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
    Bitmap bitmap;
    using (var outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapsource));
        enc.Save(outStream);
        bitmap = new Bitmap(outStream);
    }
    return bitmap;
}

Это прекрасно работает для меня.

Это то, что вы ищете?

Bitmap bmp = System.Drawing.Image.FromHbitmap(pBits);

Здесь код для установки прозрачного фона для любого растрового ресурса в словаре ресурсов(не ресурсов.resx часто используется в Windows.Формы возрастные). Я называю это методом перед метода initializecomponent () методом. Методы "ConvertBitmap (Bitmap source)" и BitmapFromSource(BitmapSource bitmapsource) упоминаются в статье из melvas выше.

private void SetBitmapResourcesTransparent()
    {
        Image img;
        BitmapSource bmpSource;
        System.Drawing.Bitmap bmp;
        foreach (ResourceDictionary resdict in Application.Current.Resources.MergedDictionaries)
        {
            foreach (DictionaryEntry dictEntry in resdict)
            {
                // search for bitmap resource
                if ((img = dictEntry.Value as Image) is Image 
                    && (bmpSource = img.Source as BitmapSource) is BitmapSource
                    && (bmp = BitmapFromSource(bmpSource)) != null)
                {
                    // make bitmap transparent and assign it back to ressource
                    bmp.MakeTransparent(System.Drawing.Color.Magenta);
                    bmpSource = ConvertBitmap(bmp);
                    img.Source = bmpSource;
                }
            }

        }

    }

Это аккуратно и быстрее света:

  return Imaging.CreateBitmapSourceFromHBitmap( bitmap.GetHbitmap(), IntPtr.Zero,
      Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions() );

Вы можете совместно использовать pixeldata между обоими пространствами имен. Вам не нужно обращаться.

Используйте SharedBitmapSource. https://stackoverflow.com/a/32841840/690656

Comments

    Ничего не найдено.