0

I'm trying to follow the following tutorial but using WPF instead of Win Forms:

A Basic Program

WPF doesn't use PictureBox, instead it uses Image.

So here goes trying to load an Image.

XAML

<Image x:Name="srcImg" Width="400" Height="300"></Image>

CS Attempt 1:

Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = My_Image.ToBitmap();

Error Message

Cannot implicitly convert type 'System.Drawing.Bitmap' 
to 'System.Windows.Media.ImageSource'

CS Attempt 2:

Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = new BitmapImage(My_Image);

Error Message

Error   1   The best overloaded method match for 'System.Windows.Media.Imaging.BitmapImage.BitmapImage(System.Uri)' has some invalid arguments  
Error   2   Argument 1: cannot convert from 'Emgu.CV.Image<Emgu.CV.Structure.Bgr,byte>' to 'System.Uri' 

Any ideas what I am doing wrong?

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Gravy
  • 12,264
  • 26
  • 124
  • 193
  • 2
    Come on, read the documentation of the stuff you are using, also the errors are crystal clear. – H.B. May 16 '13 at 20:33
  • I don't know what EMGU is, but WPF does not care about `System.Drawing` stuff and will not work with it. If you expect to achieve anything in WPF, remove all references to `System.Drawing.dll` from all your projects and start over. – Federico Berasategui May 16 '13 at 20:37

5 Answers5

8

Problem Solved. To convert the image:

Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
srcImg.Source = BitmapSourceConvert.ToBitmapSource(myImage);

BitmapSourceConvert class:

public static class BitmapSourceConvert
{
    [DllImport("gdi32")]
    private static extern int DeleteObject(IntPtr o);

    public static BitmapSource ToBitmapSource(IImage image)
    {
        using (System.Drawing.Bitmap source = image.Bitmap)
        {
            IntPtr ptr = source.GetHbitmap();

            BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                ptr,
                IntPtr.Zero,
                Int32Rect.Empty,
                System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

            DeleteObject(ptr);
            return bs;
        }
    }
}
Gravy
  • 12,264
  • 26
  • 124
  • 193
2

For the v4.4 release of EmguCV once you add the Emgu.CV.Bitmap nuget package you can convert Image<TColor, TDepth> to and from System.Drawing.Bitmap in .NetStandard using image.ToBitmap() function.

Note that for non-windows platform, System.Drawing.Bitmap require native gdi+ installed to work.

Daniel Gemer
  • 104
  • 1
  • 6
0

You can get an ImageSource from a Bitmap (wasteful but you already have ToBitmap()), or you can implement a direct conversion.

Community
  • 1
  • 1
H.B.
  • 166,899
  • 29
  • 327
  • 400
  • 1
    Hi there, I think that you misunderstood the question. I am trying to display the image stored in the EMGU (OpenCV) Image, not display an image from a file. – Gravy May 16 '13 at 20:39
  • Why in the world would you try to do that when you appear to have the path? – H.B. May 16 '13 at 20:42
  • Do you know what OpenCV is or what EMGU is? I am trying to test that I am able to display an EMGU image before I start making changes to it. – Gravy May 16 '13 at 20:45
  • @Gravy: You can display pretty much anything, you just need to convert it accordingly, if you use a foreign format there will be no shortcuts, unless you want to do EMGU->Bitmap->ImageSource, as Bitmap->ImageSource is well known. – H.B. May 16 '13 at 20:46
0

If you want to use Emgu CV with WPF, you should consider doing a user control with the Emgu's picturebox (this control only works with win forms) and then use it with WindowsFormsHost.

cap7
  • 482
  • 5
  • 24
0

Copy BitmapSourceConverter.cs from %installfolder%/Emgu/emgucv-windesktop x.x.x/Emgu.CV.WPF and add to your project to convert to BitmapSource. It is the complete version:

//----------------------------------------------------------------------------
//  Copyright (C) 2004-2017 by EMGU Corporation. All rights reserved.
//----------------------------------------------------------------------------

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Emgu.CV;
using Emgu.CV.CvEnum;

namespace Emgu.CV.WPF
{
   public static class BitmapSourceConvert
   {
      /// <summary>
      /// Delete a GDI object
      /// </summary>
      /// <param name="o">The poniter to the GDI object to be deleted</param>
      /// <returns></returns>
      [DllImport("gdi32")]
      private static extern int DeleteObject(IntPtr o);

      /// <summary>
      /// Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source
      /// </summary>
      /// <param name="image">The Emgu CV Image</param>
      /// <returns>The equivalent BitmapSource</returns>
      public static BitmapSource ToBitmapSource(IImage image)
      {
         using (System.Drawing.Bitmap source = image.Bitmap)
         {
            IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap

            BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                ptr,
                IntPtr.Zero,
                Int32Rect.Empty,
                System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

            DeleteObject(ptr); //release the HBitmap
            return bs;
         }
      }

      public static Mat ToMat(BitmapSource source)
      {

         if (source.Format == PixelFormats.Bgra32)
         {
            Mat result = new Mat();
            result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 4);
            source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step*result.Rows, result.Step);
            return result;
         } else if (source.Format == PixelFormats.Bgr24)
         {
            Mat result = new Mat();
            result.Create(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 3);
            source.CopyPixels(Int32Rect.Empty, result.DataPointer, result.Step * result.Rows, result.Step);
            return result;
         }
         else
         {
            throw new Exception(String.Format("Convertion from BitmapSource of format {0} is not supported.", source.Format));
         }
      }
   }
}
Avestura
  • 1,438
  • 14
  • 24