demo里的代码,拍几次就显示内存损坏
//线程处理函数
 private void Process()
 {
 unsafe
 { 
 while (true)
 {
 if (g_work)
 {
 int len = 0, width = 0, height = 0;
 JHCap.CameraGetImageSize(g_index, ref width, ref height);
 JHCap.CameraGetImageBufferSize(g_index, ref len, JHCap.CAMERA_IMAGE_BMP); //RGB24
 if (width == 0 || height == 0 || len == 0) continue;
 if (m_bmp!=null && (width != m_bmp.Width || height != m_bmp.Height))
 {
 m_bmp.Dispose();
 m_bmp = null;
 }
 if (m_bmp == null)
 {
 m_bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
 
 }
 //lock (pictureBox1)
 //{
 lock (m_lock)
 { 
 BitmapData bmpData = m_bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, m_bmp.PixelFormat);
 IntPtr buf = bmpData.Scan0;
 if (JHCap.CameraQueryImage(g_index, buf, ref len, JHCap.CAMERA_IMAGE_BMP) == 0) //RGB24 内存损坏
 {
 m_bmp.UnlockBits(bmpData);
 if (cbCrop.Checked || cbCrop2.Checked)
 {
 Graphics g = Graphics.FromImage(m_bmp);
 g.DrawImage(m_crop, m_crop_x, height - (int)(600 * m_scale) - m_crop_y);
 }
 JHCap.CameraShowBufferImage(m_handle, buf, width, height, true, true); //RGB24
 }
 else
 m_bmp.UnlockBits(bmpData);
 }
 //} 
 }
 }
 } 
 }
求高手解答
JHCap.CameraQueryImage(g_index, buf, ref len, JHCap.CAMERA_IMAGE_BMP) 这里的 len 是不是变动了?
在不修改相机分辨率的情况下不会变动。刚刚我抛出异常查看输出的len是一样的!
在不修改相机分辨率的情况下不会变动。刚刚我抛出异常查看输出的len是一样的!
                                    try
                                    {
                                        if (JHCap.CameraQueryImage(g_index, buf, ref len, JHCap.CAMERA_IMAGE_BMP) == 0)   //RGB24
                                        {
                                            if (len != 3686400)
                                            {
                                                MessageBox.Show(len.ToString());
                                            }
                                            m_bmp.UnlockBits(bmpData);
                                            if (cbCrop.Checked || cbCrop2.Checked)
                                            {
                                                Graphics g = Graphics.FromImage(m_bmp);
                                                g.DrawImage(m_crop, m_crop_x, height - (int)(600 * m_scale) - m_crop_y);
                                            }
                                            JHCap.CameraShowBufferImage(m_handle, buf, width, height, true, true); //RGB24
                                        }
                                        else
                                            m_bmp.UnlockBits(bmpData);
                                    }
                                    catch (Exception ex)
                                    {
                                        MessageBox.Show(len.ToString());
                                        g_work = false;
                                    }
@依人:
JHCap.CameraQueryImage 和 JHCap.CameraShowBufferImage 各自是什么功能?
@依人: 我建议做个如下的测试:
byte[] buffer = new byte[len];
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer,0);
while(true)
{
JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP) ;
}
@Launcher:
        //获取图像buffer
        [DllImport("JHCap2.DLL", EntryPoint = "CameraQueryImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int CameraQueryImage(int m_index, IntPtr p, ref int length, int option);
        //显示buffer图像
        [DllImport("JHCap2.DLL", EntryPoint = "CameraShowBufferImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int CameraShowBufferImage(IntPtr hWnd, IntPtr buf, int width, int height, bool color, bool showStretchMode);  //color :true/RGB  false/Gray showStretchMode:true/strecth
@依人: 这样的话,那你没必要同时使用 Graphics.DrawImage 和 CameraShowBufferImage.
int len = 0, width = 0, height = 0;
 JHCap.CameraGetImageSize(g_index, ref width, ref height);
 JHCap.CameraGetImageBufferSize(g_index, ref len, JHCap.CAMERA_IMAGE_BMP); //RGB24
byte[] buffer = new byte[len];
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer,0);
while(true)
{
JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP) ;
JHCap.CameraShowBufferImage(m_handle, ptr, width, height, true, true);
}
@Launcher: 你好,那依您的意思这样的代码应该怎么改写了,我发完整的代码的代码给你。您帮我改写好吗?谢谢
        //线程处理函数
        private void Process()
        {
            unsafe
            {
                while (true)
                {
                    if (g_work)
                    {
                        int len = 0, width = 0, height = 0;
                        JHCap.CameraGetImageSize(g_index, ref width, ref height);
                        JHCap.CameraGetImageBufferSize(g_index, ref len, JHCap.CAMERA_IMAGE_BMP); //RGB24
                        if (width == 0 || height == 0 || len == 0) continue;
                        using (m_bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
                        {
                            lock (pictureBox1)
                            {
                                lock (m_lock)
                                {
                                    BitmapData bmpData = m_bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, m_bmp.PixelFormat);
                                    IntPtr buf = bmpData.Scan0;
                                    try
                                    {
                                        if (JHCap.CameraQueryImage(g_index, buf, ref len, JHCap.CAMERA_IMAGE_BMP) == 0)   //RGB24
                                        {
                                            m_bmp.UnlockBits(bmpData);
                                            if (cbCrop.Checked || cbCrop2.Checked)
                                            {
                                                Graphics g = Graphics.FromImage(m_bmp);
                                                g.DrawImage(m_crop, m_crop_x, height - (int)(600 * m_scale) - m_crop_y);
                                            }
                                            JHCap.CameraShowBufferImage(m_handle, buf, width, height, true, true); //RGB24
                                        }
                                        else
                                            m_bmp.UnlockBits(bmpData);
                                    }
                                    catch (Exception)
                                    {
                                        g_work = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
@Launcher: 
Graphics.DrawImage是用来显示矩形框的,可以截图的 我发图片给您看。
g.DrawImage画的是红色的部分
@依人:
byte[] buffer = new byte[len];
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer,0);
while(true)
{
JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP) ; }
你先把这个测试过了。
@Launcher:
我用调试模式进入代码一直在while(true)里执行JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP) ;这句话 len始终是368400。。没有提示错误。
如果不调试直接运行程序,看不到任何效果!
@Launcher:
测试代码如下:
                                    try
                                    {
                                        byte[] buffer = new byte[len];
                                        IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
                                        while (true)
                                        {
                                            JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP);
                                        }
                                        //if (JHCap.CameraQueryImage(g_index, buf, ref len, JHCap.CAMERA_IMAGE_BMP) == 0)   //RGB24
                                        //{
                                        //    m_bmp.UnlockBits(bmpData);
                                        //    if (cbCrop.Checked || cbCrop2.Checked)
                                        //    {
                                        //        Graphics g = Graphics.FromImage(m_bmp);
                                        //        g.DrawImage(m_crop, m_crop_x, height - (int)(600 * m_scale) - m_crop_y);
                                        //    }
                                        //    JHCap.CameraShowBufferImage(m_handle, buf, width, height, true, true); //RGB24
                                        //}
                                        //else
                                        //    m_bmp.UnlockBits(bmpData);
                                    }
                                    catch (Exception)
                                    {
                                        g_work = false;
                                    }
@依人: 测试下这段代码:
int len = 0, width = 0, height = 0; JHCap.CameraGetImageSize(g_index, ref width, ref height); JHCap.CameraGetImageBufferSize(g_index, ref len, JHCap.CAMERA_IMAGE_BMP); //RGB24
Rectangle rc = new Rectangle(0, 0, width, height); Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
while (true) { BitmapData bmpData = null;
try { bmpData = bmp.LockBits(rc, ImageLockMode.ReadWrite, bmp.PixelFormat); JHCap.CameraQueryImage(g_index, bmpData.Scan0, ref len, JHCap.CAMERA_IMAGE_BMP); } finally { if (bmpData != null) bmp.UnlockBits(bmpData); }
using(Graphics g = Graphics.FromImage(bmp)) { g.DrawImage(m_crop, m_crop_x, height - (int)(600 * m_scale) - m_crop_y); } }
@Launcher: 你好
            unsafe
            {
                while (true)
                {
                    if (g_work)
                    {
                        int len = 0, width = 0, height = 0;
                        JHCap.CameraGetImageSize(g_index, ref width, ref height);
                        JHCap.CameraGetImageBufferSize(g_index, ref len, JHCap.CAMERA_IMAGE_BMP); //RGB24
                        Rectangle rc = new Rectangle(0, 0, width, height); Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
                        while (true)
                        {
                            BitmapData bmpData = null;
                            try
                            {
                                bmpData = bmp.LockBits(rc, ImageLockMode.ReadWrite, bmp.PixelFormat);
                                JHCap.CameraQueryImage(g_index, bmpData.Scan0, ref len, JHCap.CAMERA_IMAGE_BMP);
                            }
                            finally
                            {
                                if (bmpData != null)
                                {
                                    bmp.UnlockBits(bmpData);
                                }
                            }
                            using (Graphics g = Graphics.FromImage(bmp)) { g.DrawImage(m_crop, m_crop_x, height - (int)(600 * m_scale) - m_crop_y); }
                        }
                    }
                }
            }
没有报错,但是运行程序不显示相机拍摄的照片了 pic控件里面是空的。
@Launcher: 你好,我现在下班回家了,我吧线程的代码发给你。希望你能帮我改下。谢谢
        //线程处理函数
        private void Process()
        {
            unsafe
            {
                while (true)
                {
                    if (g_work)
                    {
                        int len = 0, width = 0, height = 0;
                        JHCap.CameraGetImageSize(g_index, ref width, ref height);
                        JHCap.CameraGetImageBufferSize(g_index, ref len, JHCap.CAMERA_IMAGE_BMP); //RGB24
                        if (width == 0 || height == 0 || len == 0) continue;
                        using (m_bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
                        {
                            lock (pictureBox1)
                            {
                                lock (m_lock)
                                {
                                    BitmapData bmpData = m_bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, m_bmp.PixelFormat);
                                    IntPtr buf = bmpData.Scan0;
                                    try
                                    {
                                        if (JHCap.CameraQueryImage(g_index, buf, ref len, JHCap.CAMERA_IMAGE_BMP) == 0)   //RGB24
                                        {
                                            m_bmp.UnlockBits(bmpData);
                                            if (cbCrop.Checked || cbCrop2.Checked)
                                            {
                                                Graphics g = Graphics.FromImage(m_bmp);
                                                g.DrawImage(m_crop, m_crop_x, height - (int)(600 * m_scale) - m_crop_y);
                                            }
                                            JHCap.CameraShowBufferImage(m_handle, buf, width, height, true, true); //RGB24
                                        }
                                        else
                                            m_bmp.UnlockBits(bmpData);
                                    }
                                    catch (Exception)
                                    {
                                        g_work = false;
                                    }
                                }
                            }
                        }
                    }
                    Thread.Sleep(100);
                }
            }
}
@依人: 对不起,我不回答了,你另请高明吧。
@Launcher: 谢谢!
JHCap.CameraQueryImage 应该查这个函数。
.NET 互操作的话,非托管内存都是要去主动释放的。
        //获取图像buffer
        [DllImport("JHCap2.DLL", EntryPoint = "CameraQueryImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
        public static extern int CameraQueryImage(int m_index, IntPtr p, ref int length, int option);