it-swarm.com.de

Gibt es eine gute Möglichkeit, zwischen BitmapSource und Bitmap zu konvertieren?

Soweit ich feststellen kann, ist der einzige Weg, um von BitmapSource zu Bitmap zu konvertieren, durch unsicheren Code ... Wie folgt (von 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;
  }
}

Um das Gegenteil zu tun:

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

Gibt es einen einfacheren Weg im Rahmen? Und warum ist es nicht da (wenn nicht)? Ich würde es für ziemlich brauchbar halten.

Ich brauche es deshalb, weil ich AForge für bestimmte Bildoperationen in einer WPF-App verwende. WPF möchte BitmapSource/ImageSource anzeigen, AForge arbeitet jedoch mit Bitmaps.

36
JohannesH

Es ist möglich, auf unsicheren Code zu verzichten, indem Sie Bitmap.LockBits verwenden und die Pixel von BitmapSource direkt in Bitmap kopieren

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;
}
58
josef.axa

Sie können diese beiden Methoden einfach verwenden:

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

Es funktioniert perfekt für mich.

29
melvas

Ist es das, wonach Sie suchen?

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

Das ist ordentlich und schneller als Licht:

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

Hier ein Code zum Festlegen eines transparenten Hintergrunds für alle Bitmap-Ressourcen in einem Ressourcenwörterbuch (nicht in Ressourcen.resx, das häufig im Windows-Alter verwendet wird) Ich nenne diese Methode vor InitializeComponent () - Methode. Die Methoden 'ConvertBitmap (Bitmap-Quelle)' und BitmapFromSource (BitmapSource-Bitmapsource) werden oben in melvas erwähnt.

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
user3318309

Sie können die Pixeldaten für beide Namespaces freigeben. Sie müssen nicht konvertieren.

Verwenden Sie die SharedBitmapSource. https://stackoverflow.com/a/32841840/690656

0
Andreas