Reputation: 35
I am creating a program in c# that records the screen and send it through a socket connection to the server. My problem is that I need to convert it to bytes to send it. Here is my code from the client, so the computer that is recording the screen:
public Form1()
{
InitializeComponent();
}
static int port = 443;
static IPAddress IP;
static Socket server;
private Bitmap bm;
private string PCname = SystemInformation.ComputerName;
private string UserName = SystemInformation.UserName;
private void btnStart_Click(object sender, EventArgs e)
{
// Connect to server
IP = IPAddress.Parse("127.0.0.1");
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Connect(new IPEndPoint(IP, port));
// Record the screen
timer1.Start();
// Send screen to server
byte[] sdata = Encoding.Default.GetBytes(pictureBox1);
server.Send(sdata, 0, sdata.Length, 0);
}
private void timer1_Tick(object sender, EventArgs e)
{
// Take screenshot
bm = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bm as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bm.Size);
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
// Show it in picturebox
pictureBox1.Image = bm;
}
private void btnStop_Click(object sender, EventArgs e)
{
timer1.Stop();
server.Close();
}
Upvotes: 0
Views: 249
Reputation: 16584
This is the basic sequence of operation of the code you supplied:
User clicks the 'Start' button Connect to server Start timer Send content of image control to server ... Repeat while timer enabled: Timer interval expires Timer handler captures screen image to image control
A couple of problems with this:
At the time that you send the content of the image control pictureBox1
to the server it has not yet been filled with the captured screen image.
You only send data to the server once, which doesn't appear to be your goal.
If your goal is to send the screen content just once then you don't need the timer. Put the code from the timer handler timer1_Tick
into your btnStart_Click
method in place of the timer1.Start()
call.
If you want to send it multiple times, then you need to put the send code in the timer handler. In this case, shift the send code from btnStart_Click
to the end of timer1_Tick
.
Also, you need some way for the server to identify that the data for a particular image has completed so that it can then process the image. In other words you need some way to frame the image - a sequence of data that is guaranteed not to appear in the data of the image itself, or at least a header that tells your server how much data to read as a valid image to process.
I'd strongly suggest you take Timothy Shields' suggestion and compress the data using PNG before sending it. So long as the server knows to expect the compressed data it can easily decompress it back to a bitmap when it is received. Using PNG will save you a lot of network time without losing any information, with just a little added overhead for the compression and decompression stages.
Upvotes: 0
Reputation: 79621
I'm not entirely sure if this is what you're looking for, but...
Here's a method to convert a Bitmap
to it's "file bytes" in the PNG format.
byte[] BitmapToBytes(Bitmap bitmap)
{
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Png);
return stream.ToArray();
}
}
Upvotes: 2