Reputation: 23
I'm in the very beginning of a team-viewer themed project.
Right now I managed to take a screenshot of the current screen as a Bitmap variable and I need to transfer it to a distant through a socket. Such a process obviously requires Serializing the Bitmap variable using json.
I have tried to do so but it seems like the Bitmap variable just isn't serialize-able. As after the serialization the json string var contains the string "system.Drawing.Bitmap". How do I convert it correctly? thanks.
The method that takes the screenshot:
public static Image TakeScreen()
{
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(0,0, 0, 0, bitmap.Size);
Console.WriteLine(bitmap.ToString());
return bitmap;
}
The Serialization:
Image image = TakeScreen();
string jsonData = JsonConvert.SerializeObject(image, Formatting.None);
Console.WriteLine(jsonData);
Upvotes: 1
Views: 4221
Reputation: 194
If you still need to transfer the image to JSON, you first need to extract the byte array and convert it to HEX or BASE64
Below I give a simple example example
public void ImageTest()
{
// get image
Image image = TakeScreen();
// conver image to bytes
byte[] img_byte_arr = ImageToBytes(image);
// creat packet
ImagePacket packet = new ImagePacket(img_byte_arr);
// conver object to json there...
// send json ...
// receive json ...
// convert json to object type of ImagePacket ...
// get bytes from ImagePacket
byte[] receive_bytes = packet.GetRawData();
// conver bytes to Image
Image receive_image = BytesToImage(receive_bytes);
}
Use this class as a container for serialization in JSON
/// <summary>
/// Packet with image
/// </summary>
public class ImagePacket
{
public string hash { get; set; } = string.Empty;
public int len { get; set; } = 0;
public string image { get; set; } = string.Empty;
public ImagePacket() { }
public ImagePacket(byte[] img_sources)
{
hash = StringHash(img_sources);
len = img_sources.Length;
image = EncodeBytes(img_sources);
}
public byte[] GetRawData()
{
byte[] data = DecodeBytes(image);
if(data.Length != len) throw new Exception("Error data len");
if(!StringHash(data).Equals(hash)) throw new Exception("Error hash");
return data;
}
}
Use the following methods for working with pictures and data transformations.
/// <summary>
/// Get original image
/// </summary>
/// <returns></returns>
public static Image TakeScreen()
{
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
return bitmap;
}
/// <summary>
/// Conver Image to byte array
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] ImageToBytes(Image value)
{
ImageConverter converter = new ImageConverter();
byte[] arr = (byte[])converter.ConvertTo(value, typeof(byte[]));
return arr;
}
/// <summary>
/// Conver byte array to Image
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static Image BytesToImage(byte[] value)
{
using(var ms = new MemoryStream(value))
{
return Image.FromStream(ms);
}
}
/// <summary>
/// Convert bytes to base64
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string EncodeBytes(byte[] value) => Convert.ToBase64String(value);
/// <summary>
/// convert base64 to bytes
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] DecodeBytes(string value) => Convert.FromBase64String(value);
/// <summary>
/// get MD5 hash from byte array
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string StringHash(byte[] value)
{
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] hashBytes = md5.ComputeHash(value);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString().ToLower();
}
}
Upvotes: 3