C# 使用Json序列化位图

C# 使用Json序列化位图,c#,json,sockets,serialization,bitmap,C#,Json,Sockets,Serialization,Bitmap,我正处于团队查看器主题项目的最开始阶段 现在,我设法将当前屏幕的屏幕截图作为位图变量,并需要通过套接字将其传输到远程屏幕。这样的过程显然需要使用json序列化位图变量 我已经尝试过这样做,但看起来位图变量无法序列化。与序列化之后一样,json字符串var包含字符串“system.Drawing.Bitmap”。如何正确转换它?谢谢 获取屏幕截图的方法: public static Image TakeScreen() { Bitmap bitmap = new Bitmap(Screen

我正处于团队查看器主题项目的最开始阶段

现在,我设法将当前屏幕的屏幕截图作为位图变量,并需要通过套接字将其传输到远程屏幕。这样的过程显然需要使用json序列化位图变量

我已经尝试过这样做,但看起来位图变量无法序列化。与序列化之后一样,json字符串var包含字符串“system.Drawing.Bitmap”。如何正确转换它?谢谢

获取屏幕截图的方法:

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;       
}
序列化:

Image image = TakeScreen();

string jsonData = JsonConvert.SerializeObject(image, Formatting.None);
Console.WriteLine(jsonData);
  • json只能序列化原语
  • 用json发送图片非常昂贵,图像或声音等数据应该通过UDP流数据传输
  • 如果仍然需要将图像传输到JSON,则首先需要提取字节数组并将其转换为十六进制或BASE64

    下面我给出一个简单的例子

    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);
    
        }
    
    将此类用作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;
            }
        }
    
    //
    ///带图像的数据包
    /// 
    公共类图像包
    {
    公共字符串哈希{get;set;}=string.Empty;
    公共整数len{get;set;}=0;
    公共字符串图像{get;set;}=string.Empty;
    公共ImagePacket(){}
    公共图像数据包(字节[]img_源)
    {
    hash=StringHash(img_源);
    len=img_.Length;
    图像=编码字节(img_源);
    }
    公共字节[]GetRawData()
    {
    字节[]数据=解码字节(图像);
    如果(data.Length!=len)抛出新异常(“错误数据len”);
    如果(!StringHash(data).Equals(hash))抛出新异常(“错误哈希”);
    返回数据;
    }
    }
    
    使用以下方法处理图片和数据转换

    /// <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();
            }
        }
    
    //
    ///获取原始图像
    /// 
    /// 
    公共静态图像截取屏幕()
    {
    位图位图=新位图(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
    Graphics g=Graphics.FromImage(位图);
    g、 CopyFromScreen(0,0,0,0,bitmap.Size);
    返回位图;
    }
    /// 
    ///将图像转换为字节数组
    /// 
    /// 
    /// 
    公共静态字节[]图像字节(图像值)
    {
    ImageConverter converter=新的ImageConverter();
    byte[]arr=(byte[])ConvertTo(value,typeof(byte[]);
    返回arr;
    }
    /// 
    ///将字节数组转换为图像
    /// 
    /// 
    /// 
    公共静态图像BytesToImage(字节[]值)
    {
    使用(var ms=新内存流(值))
    {
    返回Image.FromStream(ms);
    }
    }
    /// 
    ///将字节转换为base64
    /// 
    /// 
    /// 
    公共静态字符串EncodeBytes(字节[]值)=>Convert.ToBase64String(值);
    /// 
    ///将base64转换为字节
    /// 
    /// 
    /// 
    公共静态字节[]解码字节(字符串值)=>Convert.FromBase64String(值);
    /// 
    ///从字节数组中获取MD5哈希
    /// 
    /// 
    /// 
    公共静态字符串StringHash(字节[]值)
    {
    使用(System.Security.Cryptography.MD5 MD5=System.Security.Cryptography.MD5.Create())
    {
    byte[]hashBytes=md5.ComputeHash(值);
    StringBuilder sb=新的StringBuilder();
    for(int i=0;i
    为什么要将图像作为JSON发送?如果您使用的是HTTP,则可以作为字节数组发送。您不会将图像序列化为JSON。JSON用于序列化对象而不是字节,因此名称为Javascript
    Object
    Notation。对于图像或任何文件,您只需发送字节流。不要忘记在处理完
    图像后处理它,最好使用
    语句将其括在
    中。请查看。但是,性能可能很差,因为Json.NET将把
    Base64
    图像流完全具体化为
    字符串
    ,然后是字节数组;看见