在类中序列化和发送的摄像头帧
本文关键字:摄像头 序列化 | 更新日期: 2023-09-27 18:05:55
我正在尝试序列化MessageData类并通过网络发送它。这个类包含我需要在表单上显示的位图图片。传输位图是一个帧,一个网络摄像头需要每秒通过网络传输几次到WinForm。这个程序是一个测试,未来将分为两部分,客户端部分与接收方法和winform,和服务器部分与webcam和发送方法。
实际上,对象图片的序列化和收发不工作,如果我强迫图片从序列化网络进程传递而不是直接获取,则winform不显示任何图像。网络摄像头的画面由Emgu管理。CV库,在本地它工作得很好,但不是通过远程帧的序列化发送。下面的内容都在命名空间内
[Serializable]
public class MessageData {
public MessageData(Bitmap img){
Picture = img;
}
public static Bitmap Picture { get; set; }
}
[Serializable]
public class MessageSendData {
public MessageSendData(Bitmap img){
Picture = img;
}
public static Bitmap Picture { get; set; }
}
public partial class Idea : Form
{
//declaring global variables
private Capture capture; //takes images from camera as image frames
private bool captureInProgress; // checks if capture is executing
private TcpListener ascolto;
Bitmap bitmapricevuto;
public Idea()
{
InitializeComponent();
}
private void Idea_Load(object sender, EventArgs e)
{
}
private void ProcessFrame(object sender, EventArgs arg)
{
Image<Bgr, Byte> ImageFrame = capture.QueryFrame(); //line 1
// CamImageBox.Image = byteArrayToImage(MyImageBytes(ImageFrame.ToBitmap()));
// CamImageBox.Image = ImageFrame.ToBitmap();
Thread r = new Thread(Ricevi);
r.Start();
MessageSendData.Picture = ImageFrame.ToBitmap();
Thread s = new Thread(Spedisci);
s.Start();
lock (MessageData.Picture){
CamImageBox.Image = MessageData.Picture;
}
}
private void btnStart_Click(object sender, EventArgs e)
{
#region if capture is not created, create it now
if (capture == null)
{
try
{
capture = new Capture();
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
#endregion
if (capture != null)
{
if (captureInProgress)
{ //if camera is getting frames then stop the capture and set button Text
// "Start" for resuming capture
btnStart.Text = "Start!"; //
Application.Idle -= ProcessFrame;
}
else
{
//if camera is NOT getting frames then start the capture and set button
// Text to "Stop" for pausing capture
btnStart.Text = "Stop";
Application.Idle += ProcessFrame;
}
captureInProgress = !captureInProgress;
}
}
private void ReleaseData()
{
if (capture != null)
capture.Dispose();
}
public static void Ricevi()
{
IPAddress address = IPAddress.Parse("127.0.0.1");
TcpListener listener = new TcpListener(address, 8585);
listener.Start();
Bitmap mia;
try
{
using (TcpClient client = listener.AcceptTcpClient())
{
NetworkStream stream = client.GetStream();
IFormatter formatter = new BinaryFormatter();
while (true)
{
lock (MessageData.Picture){
MessageData.Picture = (Bitmap)formatter.Deserialize(stream);
}
}
}
}
catch(Exception ex) { }
return;
}
public static void Spedisci()
{
IPAddress address = IPAddress.Parse("127.0.0.1");
TcpClient client = new TcpClient();
try
{
client.Connect(address, 8585);
// Retrieve the network stream.
NetworkStream stream = client.GetStream();
IFormatter formatter = new BinaryFormatter();
while(true)
{
lock (MessageSendData.Picture) {
formatter.Serialize(stream, MessageSendData.Picture);
//Thread.Sleep(1000);
}
}
}
catch (Exception ex) { }
}
/*
public byte[] MyImageBytes(Image MyImage)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(MyImage, typeof(byte[]));
}
public Image byteArrayToImage(byte[] bytesArr)
{
MemoryStream memstr = new MemoryStream(bytesArr);
Image img = Image.FromStream(memstr);
return img;
}
*/
}
}'
我已经实现了两个方法:1-第一个方法转换位图在字节数组。2秒的方法转换字节数组在一个位图。直接测试它们而不通过tcp网络发送转换字节,我看到所有软件都在工作。现在我已经创建了两个方法"Invia"answers"Ricevi",它们通过将字节数组拆分为每个长度为1024的流来使用异步方法发送和接收字节数组。我对编译它的问题是关于异步任务方法返回类型。如何修复此线程任务异步问题?'
private void ProcessFrame(object sender, EventArgs arg)
{
Image<Bgr, Byte> ImageFrame = capture.QueryFrame();
invia(MyImageBytes(ImageFrame.ToBitmap()));
CamImageBox.Image = ricevi();
}
public byte[] MyImageBytes(Image MyImage)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(MyImage, typeof(byte[]));
}
Send (Invia)和Receive(Ricevi)方法的最后一个版本使用的是将字符转换为字节数组并附加到位图字节数组中以发送和接收位图。实际上我在编译过程中有问题:
public static void invia(byte[] bytetosend)
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try {
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Connect the socket to the remote endpoint. Catch any errors.
try {
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
var mahByteArray = new ArrayList<byte>();
mahByteArray.AddRange(bytetosend);
string eof = "<EOF>";
mahByteArray.Insert(0, Convert.ToByte(eof)); // Adds eof bytes to the beginning.
byte[] msg = mahByteArray.ToArray();
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes,0,bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
} catch (ArgumentNullException ane) {
Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
} catch (SocketException se) {
Console.WriteLine("SocketException : {0}",se.ToString());
} catch (Exception e) {
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
} catch (Exception e) {
Console.WriteLine( e.ToString());
}
}
public static void ricevi()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
var scambioArray = new ArrayList();
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true)
{
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
string eofr = "<EOF>";
byte[] trova = Convert.ToByte(eofr);
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
if (bytes.IndexOf(trova))
{
var mahByteArray = new ArrayList();
mahByteArray.AddRange(bytes);
mahByteArray.Remove(trova);
bytes = mahByteArray.ToArray();
break;
}
scambioArray.AddRange(bytes);
}
// Echo the data back to the client.
byte[] msg = scambioArray.ToArray();
MessageData.Picture = byteArrayToImage(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
试试这样
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static void invia(byte[] bytetosend)
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
var mahByteArray = new List<byte>();
mahByteArray.AddRange(bytetosend);
string eof = "<EOF>";
mahByteArray.Insert(0, Convert.ToByte(eof)); // Adds eof bytes to the beginning.
byte[] msg = mahByteArray.ToArray();
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void ricevi()
{
// Data buffer for incoming data.
List<byte> bytes = (new Byte[1024]).ToList();
List<byte> scambioArray = new List<byte>();
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true)
{
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
string eofr = "<EOF>";
List<byte> trova = Encoding.UTF8.GetBytes(eofr).ToList();
// An incoming connection needs to be processed.
while (true)
{
bytes = (new byte[1024]).ToList();
int bytesRec = handler.Receive(bytes.ToArray());
if (bytes.Contains(trova[0]))
{
List<byte> mahByteArray = new List<byte>();
mahByteArray.AddRange(bytes);
mahByteArray.Remove(trova[0]);
bytes = mahByteArray.ToArray().ToList();
break;
}
scambioArray.AddRange(bytes);
}
// Echo the data back to the client.
byte[] msg = scambioArray.ToArray();
MemoryStream stream = new MemoryStream(msg);
MessageData.Image = Image.FromStream(stream);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}