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