当然也可以做成以下形式,但是感觉控件的复用性不强。
方式一:委托在库中定义
图像卡库:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace WindowsFormsApplication1
{
public delegate void ImageReceived(ushort[] imageDatas);
public class ImageCardLib
{
private int imageSize;
private ushort[] imageDatas;
private void generateData()
{
Random rd = new Random();
int ii = rd.Next(0, 65535);
for (int i = 0; i < imageSize; i++)
{
imageDatas[i] = (ushort)ii;
}
}
public ImageReceived ReceiveCallback;
public void DmaRecv(int imageSize)
{
ReceiveCallback = new ImageReceived(beforeDisplayImage);
new Thread(new ThreadStart(delegate
{
while (true)
{
this.imageSize = imageSize;
imageDatas = new ushort[imageSize];
generateData();
ReceiveCallback(imageDatas);
System.Threading.Thread.Sleep(10);
}
})).Start();
}
private void beforeDisplayImage(ushort[] imageDatas)
{
//先做点什么
}
}
}
主界面:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int imageSize = 128 * 128;
public ushort[] imageReceiveBuffer; //= new byte[128 * 128*2];
public Form1()
{
InitializeComponent();
ImageCardLib g = new ImageCardLib();
imageReceiveBuffer = new ushort[imageSize];
g.DmaRecv(imageSize);//imageReceiveBuffer, 128 * 128*2,
g.ReceiveCallback += DisplayImage;
}
private void DisplayImage(ushort[] imageReceiveBuffer)
{
byte[] frameArray = new byte[128 * 128 * 2];
ushort[] temp = new ushort[imageReceiveBuffer.Length];
new Thread(new ThreadStart(delegate
{
Array.Copy(imageReceiveBuffer, temp, imageReceiveBuffer.Length);
lock (this)
{
for (int j = 0; j < imageSize; ++j)
{
Array.Copy(BitConverter.GetBytes(temp[j]), 0, frameArray, j * 2, 2);
}
}
this.Invoke(new MethodInvoker(() =>
{
imageDisplayer1.SetImageData(frameArray);
}));
})).Start();
}
}
}
注意:
因为像素点用16bit表示,因此重点存储用ushort[]
如果用byte[],如下:
for (int i = 0; i < 128; i++)
for (int j = 0; j < 128; j++)
{
frameArray[i * 128 * 2 + j * 2] = (byte)(ii % 256);
frameArray[i * 128 * 2 + j * 2 + 1] = (byte)(ii / 256);
}
另外,从库中获得的数据使用之前先Array.Copy,Lock(this){},避免数据重叠
方式二:委托在主界面中定义
委托被当作参数传递给了库。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace WindowsFormsApplication1
{
public delegate void ImageReceived(ushort[] imageDatas);
public class ImageCardLib
{
private int imageSize;
private ushort[] imageDatas;
private void generateData()
{
Random rd = new Random();
int ii = rd.Next(0, 65535);
for (int i = 0; i < imageSize; i++)
{
imageDatas[i] = (ushort)ii;
}
}
public void DmaRecv(int imageSize, ImageReceived imgrev)
{
new Thread(new ThreadStart(delegate
{
while (true)
{
this.imageSize = imageSize;
imageDatas = new ushort[imageSize];
generateData();
//data = imageDatas;
imgrev += then;
imgrev(imageDatas);
System.Threading.Thread.Sleep(10);
}
})).Start();
}
private void then(ushort[] imageDatas)
{
//做点什么
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int imageSize = 128 * 128;
private ImageReceived ReceiveCallback;
public ushort[] imageReceiveBuffer;
public Form1()
{
InitializeComponent();
ImageCardLib g = new ImageCardLib();
imageReceiveBuffer = new ushort[imageSize];
ReceiveCallback = new ImageReceived(DisplayImage);
g.start();
g.DmaRecv(imageSize,ReceiveCallback);
}
private void DisplayImage(ushort[] imageReceiveBuffer)
{
byte[] frameArray;
ushort[] temp = new ushort[imageReceiveBuffer.Length];
new Thread(new ThreadStart(delegate
{
Array.Copy(imageReceiveBuffer, temp, imageReceiveBuffer.Length);
frameArray = new byte[temp.Length*2];
lock (this)
{
for (int j = 0; j < imageSize; ++j)
{
Array.Copy(BitConverter.GetBytes(temp[j]), 0, frameArray, j * 2, 2);
}
}
this.Invoke(new MethodInvoker(() =>
{
imageDisplayer1.SetImageData(frameArray);
}));
})).Start();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
ReceiveCallback -= DisplayImage;
}
}
}
方式三:定义新事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
namespace WindowsFormsApplication1
{
public class AsyncPaintEventArgs : EventArgs
{
public ushort[] TaskimageDatas { get; set; }
}
//事件是属于类的成员,所以是要放在类的内部的。委托,属于一个定义。其实是和类、接口类似的。通常是放在外部的。因为大多数委托都是要被重用的。
public class ImageCardLib
{
public EventHandler<AsyncPaintEventArgs> AsyncPaint;
private int imageSize;
private ushort[] imageDatas;
private void generateData()
{
Random rd = new Random();
int ii = rd.Next(0, 65535);
for (int i = 0; i < imageSize; i++)
{
imageDatas[i] = (ushort)ii;
}
}
public void DmaRecv(int imageSize)
{
AsyncPaint += beforeDisplayImage;
this.imageSize = imageSize;
imageDatas = new ushort[imageSize];
new Thread(new ThreadStart(delegate
{
while (true)
{
generateData();
if (AsyncPaint != null)
{
var args = new AsyncPaintEventArgs
{
TaskimageDatas=imageDatas
};
AsyncPaint(this, args)
}
System.Threading.Thread.Sleep(10);
}
})).Start();
}
private void beforeDisplayImage(object sender, AsyncPaintEventArgs e)
{
//先做点什么
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int imageSize = 128 * 128;
public Form1()
{
InitializeComponent();
ImageCardLib g = new ImageCardLib();
g.DmaRecv(imageSize);
g.AsyncPaint += ucImage1_AsyncPaint;
this.FormClosing += (_, __) =>
{
g.AsyncPaint -= ucImage1_AsyncPaint;
};
}
private void ucImage1_AsyncPaint(object sender, AsyncPaintEventArgs e)
{
if (e != null && e.TaskimageDatas != null)
{
ushort[] temp = new ushort[e.TaskimageDatas.Length];
byte[] frameArray = new byte[temp.Length*2];
Array.Copy(e.TaskimageDatas, temp, e.TaskimageDatas.Length);
lock (this)
{
for (int j = 0; j < imageSize; ++j)
{
Array.Copy(BitConverter.GetBytes(temp[j]), 0, frameArray, j * 2, 2);
}
}
this.Invoke(new MethodInvoker(() =>
{
imageDisplayer1.SetImageData(frameArray);
}));
}
}
}
}