C# 如何正确序列化Icon对象 避免反序列化后出现质量损失
问题根因
System.Drawing.Icon类的默认序列化实现仅会保留默认尺寸(通常为32×32)的图标帧,多尺寸、更高清的图标帧会在序列化时被直接丢弃,这就是反序列化后图标质量下降的核心原因。BinaryFormatter自身不会处理Icon的多帧数据留存,因此不能直接用来序列化Icon列表。
要实现无损序列化,核心思路是不依赖Icon类的默认序列化逻辑,直接读写Icon的完整原始字节流
无损序列化实现方案
方案1:基于BinaryFormatter的适配实现
通过提前将Icon转为完整字节流再序列化,避免默认逻辑丢弃帧数据:
序列化代码
List<Icon> icons = GetIcons(); // 获取图标列表的原有逻辑 List<byte[]> iconBytesList = new List<byte[]>(); // 逐个将Icon转为完整的原始字节数组 foreach (var icon in icons) { using (MemoryStream ms = new MemoryStream()) { icon.Save(ms); iconBytesList.Add(ms.ToArray()); } } // 序列化字节数组列表,字节数据序列化无损耗 BinaryFormatter formatter = new BinaryFormatter(); using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { formatter.Serialize(fs, iconBytesList); }
反序列化代码
BinaryFormatter formatter = new BinaryFormatter(); List<byte[]> iconBytesList; // 先反序列化得到字节数组列表 using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { iconBytesList = (List<byte[]>)formatter.Deserialize(fs); } // 逐个将字节数组转回完整Icon对象 List<Icon> icons = new List<Icon>(); foreach (var bytes in iconBytesList) { using (MemoryStream ms = new MemoryStream(bytes)) { icons.Add(new Icon(ms)); } }
方案2:规避BinaryFormatter的更安全实现
由于BinaryFormatter存在已知的安全风险,也可以直接手动读写文件实现,无需依赖序列化器:
// 序列化写入文件 List<Icon> icons = GetIcons(); using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) using (var writer = new BinaryWriter(fs)) { // 写入图标总数 writer.Write(icons.Count); foreach (var icon in icons) { using var ms = new MemoryStream(); icon.Save(ms); byte[] iconBytes = ms.ToArray(); // 先写入当前图标字节长度,再写入字节内容 writer.Write(iconBytes.Length); writer.Write(iconBytes); } } // 反序列化读取文件 List<Icon> icons = new List<Icon>(); using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) using (var reader = new BinaryReader(fs)) { int iconCount = reader.ReadInt32(); for (int i = 0; i < iconCount; i++) { int byteLen = reader.ReadInt32(); byte[] iconBytes = reader.ReadBytes(byteLen); using var ms = new MemoryStream(iconBytes); icons.Add(new Icon(ms)); } }
内容的提问来源于stack exchange,提问作者Tsaras
相关产品推荐
相关产品推荐

