InteropBitmap指定内存,绑定WPF的Imag控件时刷新问题。

1.InteropBitmap指定内存,绑定WPF的Imag控件的Source属性

创建InteropBitmap的时候,像素的格式必须为PixelFormats.Bgr32,

如果不是的话在绑定到Image控件的Source属性,刷新新界面(BitmapSource.Invalidate())的时候会造成内存泄露。

2. 内存映射:

    //内存共享类
    internal class Win32Mess
    {
        [DllImport("VCamBridge.dll", EntryPoint = "InitializeCam", CallingConvention = CallingConvention.Cdecl)]
        public static extern byte InitializeCam(string header, string body);
        [DllImport("VCamBridge.dll", EntryPoint = "SetFrameInfo", CallingConvention = CallingConvention.Cdecl)]
        public static extern void SetFrameInfo(int width, int height);

        [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
        public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr OpenFileMapping(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);

        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool CloseHandle(IntPtr handle);

        [DllImport("kernel32", EntryPoint = "GetLastError")]
        public static extern int GetLastError();

        const int ERROR_ALREADY_EXISTS = 183;

        const int FILE_MAP_COPY = 0x0001;
        public const int FILE_MAP_WRITE = 0x0002;
        const int FILE_MAP_READ = 0x0004;
        public const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004; //0xF001F;

        const int PAGE_READONLY = 0x02;
        const int PAGE_READWRITE = 0x04;
        const int PAGE_WRITECOPY = 0x08;
        const int PAGE_EXECUTE = 0x10;
        const int PAGE_EXECUTE_READ = 0x20;
        const int PAGE_EXECUTE_READWRITE = 0x40;

        const int SEC_COMMIT = 0x8000000;
        const int SEC_IMAGE = 0x1000000;
        const int SEC_NOCACHE = 0x10000000;
        const int SEC_RESERVE = 0x4000000;

        const int INVALID_HANDLE_VALUE = -1;

        IntPtr m_hSharedMemoryFile = IntPtr.Zero;
        IntPtr m_pwData = IntPtr.Zero;
        bool m_bAlreadyExist = false;
        bool m_bInit = false;
        public bool IsOpen
        {
            get { return this.m_bInit; }
        }
        long m_MemSize = 0;

        public Win32Mess()
        {
        }
        ~Win32Mess()
        {
            Close();
        }

        /// 
        /// 初始化共享内存
        /// 
        /// 共享内存名称
        /// 共享内存大小
        /// 
        public int Init(string strName, long lngSize)
        {
            if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
            m_MemSize = lngSize;
            if (strName.Length > 0)
            {
                //创建内存共享体(INVALID_HANDLE_VALUE)
                m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);
                if (m_hSharedMemoryFile == IntPtr.Zero)
                {
                    m_bAlreadyExist = false;
                    m_bInit = false;
                    return 2; //创建共享体失败
                }
                else
                {
                    if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                    {
                        m_bAlreadyExist = true;
                    }
                    else                                         //新创建
                    {
                        m_bAlreadyExist = false;
                    }
                }
                //---------------------------------------
                //创建内存映射
                m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)lngSize);
                if (m_pwData == IntPtr.Zero)
                {
                    m_bInit = false;
                    CloseHandle(m_hSharedMemoryFile);
                    return 3; //创建内存映射失败
                }
                else
                {
                    m_bInit = true;
                    if (m_bAlreadyExist == false)
                    {
                        //初始化
                    }
                }
                //----------------------------------------
            }
            else
            {
                return 1; //参数错误     
            }

            return 0;     //创建成功
        }
        public InteropBitmap GetImage(System.Drawing.Size sizeMemory)
        {
            if (m_bInit)
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(m_hSharedMemoryFile,
                    (int)sizeMemory.Width, (int)sizeMemory.Height, PixelFormats.Bgr32,
                     (int)(sizeMemory.Width * PixelFormats.Bgr32.BitsPerPixel / 8), 0) as InteropBitmap;
            else
                return null;

        }

        /// 
        /// 关闭共享内存
        /// 
        public void Close()
        {
            if (m_bInit)
            {
                UnmapViewOfFile(m_pwData);
                CloseHandle(m_hSharedMemoryFile);
                m_hSharedMemoryFile = IntPtr.Zero;
                m_bInit = false;
            }
        }

        /// 
        /// 读数据
        /// 
        /// 数据
        /// 起始地址
        /// 个数
        /// 
        public int Read(ref byte[] bytData, int lngAddr, int lngSize)
        {
            if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            return 0;     //读成功
        }

        /// 
        /// 写数据
        /// 
        /// 数据
        /// 起始地址
        /// 个数
        /// 
        public int Write(byte[] bytData, int lngAddr, int lngSize)
        {
            if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            return 0;     //写成功
        }
        public int Write(IntPtr lngAddr, int lngSize)
        {
            if (lngSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                CopyMemory(m_pwData, lngAddr, lngSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            return 0;     //写成功
        }
    }

 

 

 
posted @ 2014-07-01 10:28  亲福  阅读(1344)  评论(0编辑  收藏  举报