首页 新闻 会员 周边 捐助

c# 线程 Bitmap

0
[待解决问题]

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);
}
//}
}
}
}
}

 

求高手解答

依人的主页 依人 | 初学一级 | 园豆:14
提问于:2014-07-22 16:01
< >
分享
所有回答(2)
1

JHCap.CameraQueryImage(g_index, buf, ref len, JHCap.CAMERA_IMAGE_BMP)  这里的 len 是不是变动了?

Launcher | 园豆:45050 (高人七级) | 2014-07-22 16:26

在不修改相机分辨率的情况下不会变动。刚刚我抛出异常查看输出的len是一样的!

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 16:53

在不修改相机分辨率的情况下不会变动。刚刚我抛出异常查看输出的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;
                                    }

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 16:53

@依人: 

JHCap.CameraQueryImage 和 JHCap.CameraShowBufferImage 各自是什么功能?

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-07-22 17:02

@依人: 我建议做个如下的测试:

byte[] buffer = new byte[len];

IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer,0);

while(true)

{

JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP) ;
}

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-07-22 17:05

@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

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 17:09

@依人: 这样的话,那你没必要同时使用 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);

}

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-07-22 17:19

@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;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 17:27

@Launcher: 

Graphics.DrawImage是用来显示矩形框的,可以截图的 我发图片给您看。

g.DrawImage画的是红色的部分

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 17:30

@依人: 

byte[] buffer = new byte[len];

IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer,0);

while(true)

{

JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP) ; }

你先把这个测试过了。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-07-22 17:34

@Launcher: 

我用调试模式进入代码一直在while(true)里执行JHCap.CameraQueryImage(g_index, ptr, ref len, JHCap.CAMERA_IMAGE_BMP) ;这句话 len始终是368400。。没有提示错误。

如果不调试直接运行程序,看不到任何效果!

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 17:44

@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;
                                    }

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 17:45

@依人: 测试下这段代码:

            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);                 }             }

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-07-22 17:53

@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控件里面是空的。

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 17:58

@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);
                }
            }

        }

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 18:02

@依人: 对不起,我不回答了,你另请高明吧。

支持(0) 反对(0) Launcher | 园豆:45050 (高人七级) | 2014-07-22 18:03

@Launcher: 谢谢!

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-23 08:27
0

JHCap.CameraQueryImage 应该查这个函数。

.NET 互操作的话,非托管内存都是要去主动释放的。

Firen | 园豆:5385 (大侠五级) | 2014-07-22 17:02

        //获取图像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);

支持(0) 反对(0) 依人 | 园豆:14 (初学一级) | 2014-07-22 17:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册