简体   繁体   中英

BitmapImage -> Bitmap -> Mat -> Bitmap ->BitmapImage Convert

I'm developing a kind of real-time video chatting and also trying to make a binary image using OpenCV. I'm working on C# WPF and I have to draw images on Canvas. This means I need 'BitmapImage' to draw the screen. But I have to use 'Mat' to make a binary image. So I tried many solutions found from StackOverflow but never worked for me. Below is my code.

   Mat tempMat = new Mat();
   Bitmap tempImage = BitmapImage2Bitmap(tempOriginal);
   tempMat = BitmapConverter.ToMat(tempImage);

Converting BitmapImage to Bitmap first, and then convert Bitmap to Mat . After that, make image binary. Below is the code.

Mat hsv = new Mat();
Mat binary = new Mat();
Cv2.CvtColor(tempMat, hsv, ColorConversionCodes.BGR2HSV);
Cv2.InRange(hsv, new Scalar(minH, minS, minV), new Scalar(maxH, maxS, maxV), binary);
tempMat = binary.Clone();
binary.Release();
hsv.Release();

After this operation, convert the mat back to Bitmap and BitmapImage again. Below is the code.

tempImage = BitmapConverter.ToBitmap(tempMat);
BitmapImage resultBitmap = Bitmap2BitmapImage(tempImage);
ipWindow.ipView.ImageSource = resultBitmap;

I searched a lot and tried several solutions to change Bitmap to BitmapImage and vice versa. But never worked. Below codes are solutions I tried. I'm new to C# and also WPF, so I have no idea how to solve this problem. Thanks for reading this long question.

Solution1. BitmapImage -> Bitmap

private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage){
            
            using (MemoryStream outStream = new MemoryStream())
            {
                BitmapEncoder enc = new BmpBitmapEncoder();
                enc.Frames.Add(BitmapFrame.Create(bitmapImage));
                enc.Save(outStream);
                Bitmap bitmap = new Bitmap(outStream);
                outStream.Close();

                return new Bitmap(bitmap);
            }
        }

Solution1. Bitmap -> BitmapImage

private BitmapImage Bitmap2BitmapImage(Bitmap bitmap){
            BitmapSource i = Imaging.CreateBitmapSourceFromHBitmap(
                           bitmap.GetHbitmap(),
                           IntPtr.Zero,
                           Int32Rect.Empty,
                           BitmapSizeOptions.FromEmptyOptions());
            return (BitmapImage)i;
}

Solution2. Bitmap -> BitmapImage

private BitmapImage Bitmap2BitmapImage(Bitmap inputBitmap){
Bitmap bitmap = new Bitmap(inputBitmap.Width, inputBitmap.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Bmp);
            var bi = new BitmapImage();
            bi.BeginInit();
            bi.StreamSource = ms;
            bi.CacheOption = BitmapCacheOption.OnLoad;
            bi.EndInit();
            return bi;
}

Solution3. Bitmap -> BitmapImage

private BitmapImage Bitmap2BitmapImage(Bitmap inputBitmap){
using (var memory = new MemoryStream())
            {
                inputBitmap.Save(memory, ImageFormat.Png);
                memory.Position = 0;

                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                bitmapImage.Freeze();

                return bitmapImage;
}

Solution4. Bitmap -> BitmapImage

private BitmapImage Bitmap2BitmapImage(Bitmap inputBitmap){
MemoryStream ms = new MemoryStream();
            inputBitmap.Save(ms, ImageFormat.Bmp);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            ms.Seek(0, SeekOrigin.Begin);
            image.StreamSource = ms;
            image.EndInit();
            return image;
}

I solved. The problems were two. One was OpenCvSharp and another was Bitmap to BitmapImage. Actually OpenCvSharp problem was severe so I couldn't find proper solutions between above. But after I uninstall and reinstall the openCvSharp, I found out what solution works for me. The code is below.

private BitmapImage Bitmap2BitmapImage(Bitmap inputBitmap)
        {
            using (var memory = new MemoryStream())
            {
                inputBitmap.Save(memory, ImageFormat.Png);
                memory.Position = 0;

                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                bitmapImage.Freeze();

                return bitmapImage;
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM