1.背景:
硬件:DALSA的2K彩色相机,内触发。
软件:C#开发,原本是一套黑白相机代码,使用DALSA提供的SDK,没有用OPENCV或者HALCON来进行图片保存,用的DALSA自己给的write和save方法,这一套代码在以前的4k黑白相机上运行无问题,最近设备换成了2k彩色相机,存图出现了问题。
2.代码大致思路:
相机各参数已经保存为ccf文件,代码读取ccf文件的内容,在回调函数中,用marshal.copy将数据从非托管内存指针赋值到托管数组,然后自己创建了一个imageData类,用这个对象来接收内存数据,然后将对象放入一个队列中。另起一个线程,判断之前的队列是否为空,不为空则拿队列内的数据,然后保存。
回调函数代码:
void m_Xfer_XferNotify(object sender, SapXferNotifyEventArgs argsNotify)
{
if (argsNotify.Trash) return;
//获取m_Buffers的地址(指针)
IntPtr addr = IntPtr.Zero;
m_Buffers.GetAddress(out addr);
int count = m_Buffers.Count;
SapFormat format = m_Buffers.Format;
int height = m_Buffers.Height; //1000
int width = m_Buffers.Width; //2048
//2021-11-18黑白转彩色,由于彩色rgb图像为三通道,所以将size做*3处理。
int size = width * height*3;//图片大小
byte[] data = new byte[size];
//将数据从非托管内存指针复制到托管8位无符号整数数组(0至size)
Marshal.Copy(addr, data, 0, size);
ImageData imageData = new ImageData(data, width, height, size);
inQueue.Enqueue(imageData);
m_Buffers.ReleaseAddress(addr);
}
另外一个线程,保存图片用:
void save()
{
while (true)
{
if (!inQueue.IsEmpty)
{
ImageData imageData;
inQueue.TryDequeue(out imageData);
SapBuffer m_Buffers_save = new SapBuffer(3, imageData.ImageWidth, imageData.ImageHeight, sapFormat, memoryType);
m_Buffers_save.Create();
long datasize = imageData.ImageDataSize;
GCHandle dataBufHandle = GCHandle.Alloc(imageData.DataBuffer, GCHandleType.Pinned);
IntPtr saveBuffer = dataBufHandle.AddrOfPinnedObject();
m_Buffers_save.Write(0, (int)datasize, saveBuffer);
m_Buffers_save.Save(urlFromJava + saveCunt + ".bmp", "-format bmp");
Console.WriteLine(saveCunt);
saveCunt++;
dataBufHandle.Free();
m_Buffers_save.Clear();
m_Buffers_save.Destroy();
m_Buffers_save.Dispose();
}
}
}
3.问题点:
①刚开始采图,C#报错保存方法中的write方法有问题,就是那个存图用的临时对象,不够大:
②上述错误,点击是,则很快又弹窗一次错误,点击否则可以正常采图,但是保存下来的图片很多是纯黑的,没有任何内容:
正常图:
黑图: