-1

I'm trying to convert a Bitmap to a BitmapImage in WPF. Basically, I'm starting with a Bitmap created in memory (from another process) and I need to use it elsewhere, but as a BitmapImage.

I found this answer question 6484357, but the author's function Bitmap2BitmapImage does not work (at least in DotNet4.5) as there is no such method called Imaging.CreateBitmapSourceFromHBitmap - so no luck there (at least no way to convert to a VB.Net equivalent function).

Community
  • 1
  • 1
MC9000
  • 2,076
  • 7
  • 45
  • 80

1 Answers1

1

Incorporating question 6484357 and translated to vb.net

Imports System
Imports System.Drawing
Imports System.IO
Imports System.Windows
Imports System.Windows.Interop
Imports System.Windows.Media.Imaging

Namespace StackConsoleTesting
Class Program

    Private Function BitmapImage2Bitmap(bitmapImage As BitmapImage) As Bitmap
        BitmapImage bitmapImage = new BitmapImage(new Uri("../Images/test.png", UriKind.Relative));

        Using outStream = New MemoryStream()
            Dim enc As BitmapEncoder = New BmpBitmapEncoder()
            enc.Frames.Add(BitmapFrame.Create(bitmapImage))
            enc.Save(outStream)
            Dim bitmap As New System.Drawing.Bitmap(outStream)

            Return New Bitmap(bitmap)
        End Using
    End Function

    <System.Runtime.InteropServices.DllImport("gdi32.dll")> _
    Public Shared Function DeleteObject(hObject As IntPtr) As Boolean
    End Function

    Private Function Bitmap2BitmapImage(bitmap As Bitmap) As BitmapImage
        Dim hBitmap As IntPtr = bitmap.GetHbitmap()
        Dim retval As BitmapImage

        Try

            Dim bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions())

            Dim encoder = New BmpBitmapEncoder()
            Dim memoryStream = New MemoryStream()

            encoder.Frames.Add(BitmapFrame.Create(bitmapSource))
            encoder.Save(memoryStream)

            retval.BeginInit()
            retval.StreamSource = New MemoryStream(memoryStream.ToArray())
            retval.EndInit()

            memoryStream.Close()

        Return retval
    End Function
End Class
End Namespace
Trae Moore
  • 1,759
  • 3
  • 17
  • 32
  • 1
    I was importing System.Drawing.Imaging, so I had to change Imaging.CreateBitmapSourceFromHBitmap to System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap – MC9000 Nov 17 '13 at 06:15
  • Spoke too soon. The DirectCast generates an error. "Unable to cast object of type 'System.Windows.Interop.InteropBitmap' to type 'System.Windows.Media.Imaging.BitmapImage'." – MC9000 Nov 17 '13 at 06:32
  • I'm working on getting this to work properly, the referenced question (marked as a duplicate) creates a bitmapsource - that works, but the question was to create a BITMAP - the functions provided do not work as coded (at least not in VB.Net) - I should have a working function soon once I research a bit more. – MC9000 Nov 17 '13 at 20:12
  • See correction above at the end of Trae's post (not sure why, but the edit did not show up as a code block). It's fully tested and works fine. – MC9000 Nov 17 '13 at 20:30
  • 1
    I changed the JpegBitmapEncoder to BmpBitmapEncoder for performance Dim encoder = New BmpBitmapEncoder() – MC9000 Nov 17 '13 at 20:34
  • @MC9000 Updated the answer with your performance enhancement. – Trae Moore Nov 17 '13 at 20:55