Vraag Is er een goede manier om te converteren tussen BitmapSource en Bitmap?


Voor zover ik kan vertellen is de enige manier om van BitmapSource naar Bitmap te converteren door onveilige code ... Zoals dit (uit Lesters WPF-blog):

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;
  }
}

Om het omgekeerde te doen:

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

Is er een gemakkelijkere manier in het kader? En wat is de reden dat het er niet is (als het dat niet is)? Ik zou denken dat het redelijk bruikbaar is.

De reden dat ik het nodig heb is omdat ik AForge gebruik om bepaalde beeldbewerkingen uit te voeren in een WPF-app. WPF wil BitmapSource / ImageSource tonen, maar AForge werkt op Bitmaps.


35
2018-02-17 20:59


oorsprong


antwoorden:


Het is mogelijk om te doen zonder onveilige code te gebruiken door te gebruiken Bitmap.LockBits en kopieer de pixels van de BitmapSource rechtstreeks naar de 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;
}

55
2018-05-24 13:35



U kunt deze twee methoden gewoon gebruiken:

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;
}

Het werkt perfect voor mij.


28
2018-02-21 10:31



Is dit wat je zoekt?

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

1
2018-02-17 22:23



Hier een code om een ​​transparante achtergrond in te stellen voor elke bitmapresource in een Resource-woordenboek (niet Resources.resx die vaak wordt gebruikt in Windows.Forms age). Ik roep deze methode vóór InitializeComponent () - methode. De methodes 'ConvertBitmap (Bitmap source)' en BitmapFromSource (BitmapSource bitmapsource) worden genoemd in de post van melvas hierboven.

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;
                }
            }

        }

    }

1
2017-11-18 11:35



Dit is netjes en sneller dan licht:

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

1
2018-06-10 12:12



U kunt de pixeldata tussen beide naamruimten delen. Je hoeft niet te converteren.

Gebruik de SharedBitmapSource. https://stackoverflow.com/a/32841840/690656


0
2018-06-23 13:12