坑.001

1、问题:

 (20190821)做 视频的图像分析的时候,遇到 release版的exe中 BitmapSourceConvert.ToBitmapSource(IImage image)函数报错,而且是 直接内存错误 catch抓不到 全局的异常处理函数Application_DispatcherUnhandledException(...)也抓不到...  exe直接崩溃...

  具体的 出错函数位置是:“IntPtr ptr = source.GetHbitmap();”  ZC:这里 获取 bitmap的句柄 为啥会报错,想不明白... 难道是 bitmap里面是空的?无效的?才会 导致 取句柄的时候出错?

2、我做的尝试:

 2.1、个人感觉 是内存过早被GC释放??然后 踩到了 不该踩的内存??  于是 尝试 System.Drawing.Bitmap.LockBits(...)锁定内存,我的想法 内存锁住了 总该可以使用了吧?但是 LockBits()之后 exe依旧会崩溃...

 2.2、找了 另一种 Bitmap 转 BitmapSource的方式,这是 直接取的内存(不是通过句柄,∴不需要获取句柄了),这就说明 Bitmap里面的内存是 OK的,仅仅是 取句柄时 出错了(∴ LockBits不管用)...

  (1)想知道到底为啥 Bitmap.GetHbitmap()会出错:现在不知道怎么弄,暂时不知道 怎么看 Bitmap.GetHbitmap()里面的源码/汇编,网上搜也没有这个问题... 暂时搁置...

3、代码:

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)
        {
            try
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                //System.Drawing.Bitmap source = image.Bitmap;
                using (System.Drawing.Bitmap source = image.Bitmap)
                {
                    Console.WriteLine("ToBitmapSource(...) - 1");
                    BitmapData bd = source.LockBits(
                        new Rectangle(0, 0, source.Width, source.Height),
                        System.Drawing.Imaging.ImageLockMode.ReadWrite, source.PixelFormat);
                    unsafe
                    {
                        int* pii = (int*)bd.Scan0;
                        Console.WriteLine("ToBitmapSource(...) - 1.1 : {0}", pii[0]);
                    }

                    //IntPtr pp = image.Ptr;
                    //unsafe
                    //{
                    //    BitmapData bitmapData = source.LockBits(
                    //        new Rectangle(0, 0, source.Width, source.Height),
                    //        System.Drawing.Imaging.ImageLockMode.ReadWrite, source.PixelFormat);
                    //    int* pii = (int*)bitmapData.Scan0;
                    //    Console.WriteLine("ToBitmapSource(...) - 1 : {0} : {1}, {2}, {3}",
                    //        bitmapData.PixelFormat, pii[0], pii[10], pii[20]);

                    //        //PixelFormat.Format24bppRgb

                    //    int* pi = (int*)pp;
                    //    Console.WriteLine("ToBitmapSource(...) - 2 : {0}; {1}, {2}:{3}, {4}, {5}",
                    //        source, source.Size, image.Ptr, pi[0], pi[10], pi[20]);
                    //}

                    Console.WriteLine("ToBitmapSource(...) - 2");
                    IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
                    
                    Console.WriteLine("ToBitmapSource(...) - 3");

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

                    sw.Stop();
                    Console.WriteLine("ToBitmapSource(...) ElapsedMilliseconds : {0}", sw.ElapsedMilliseconds);
                    //source.UnlockBits(bd);
                    DeleteObject(ptr); //release the HBitmap
                    return bs;
                }
            }
            catch (Exception _ex)
            {
                string str = "ToBitmapSource(...) err : " + _ex.Message+", ["+DateTime.Now+"]";
                Console.WriteLine(str);
                Trace.TraceError(str);

                return null;
            }
        }

        //public static BitmapSource ToBitmapSource(Mat _mat)
        //{
        //    //try
        //    //{
        //    _mat.to.Bitmap
        //    Bitmap source = Image.FromStream(new MemoryStream(_mat.Data));
        //    Bitmap source = new Bitmap(_mat.Width, _mat.Height);
        //    source
        //    Bitmap ^ test = gcnew Bitmap(matToConvert.rows, matToConvert.cols, 4 * matToConvert.rows, System::Drawing::Imaging::PixelFormat::Format4bppIndexed, IntPtr(matToConvert.data));

        //    Console.WriteLine("_mat.NumberOfChannels : {0}", _mat.NumberOfChannels);
        //    BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(
        //        _mat.Ptr, _mat.Width, _mat.Height, PixelFormats.Bgr24, (int)(_mat.Width * PixelFormats.Bgr24.BitsPerPixel / 8), 0);
        //    return bs;
        //    //}
        //    //catch (Exception _ex)
        //    //{
        //    //    string str = "ToBitmapSource(Mat) err : " + _ex.Message + ", [" + DateTime.Now + "]";
        //    //    Console.WriteLine(str);
        //    //    Trace.TraceError(str);

        //    //    return null;
        //    //}
        //}

// ZC: 这里的转换函数 是来自:“Bitmap转换到BitmapSource - koloumi的博客 - CSDN博客.html(https://blog.csdn.net/koloumi/article/details/80577249)”
// ZC:  该方法 美中不足:多了一次MemoryStream操作,需要复制内存。 public static BitmapSource ToBitmapSource(Mat _mat) { System.Windows.Media.Imaging.BitmapFrame bf = null; //Stopwatch sw = new Stopwatch(); //sw.Start(); using (System.Drawing.Bitmap bmp = _mat.Bitmap) { using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { //Console.WriteLine("zzzzz(...) - 1"); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); //Console.WriteLine("zzzzz(...) - 2"); bf = System.Windows.Media.Imaging.BitmapFrame.Create(ms, System.Windows.Media.Imaging.BitmapCreateOptions.None, System.Windows.Media.Imaging.BitmapCacheOption.OnLoad); //sw.Stop(); //Console.WriteLine("zzzzz(...) ElapsedMilliseconds : {0}", sw.ElapsedMilliseconds); //Console.WriteLine("zzzzz(...) - 3"); } } return bf; } }

4、

5、

猜你喜欢

转载自www.cnblogs.com/csskill/p/11387092.html
001