如何在C#中序列化HTuple?反序列化后无法使用问题求助
问题分析
Halcon的HTuple和HObject类型并非为.NET标准序列化(BinaryFormatter/Json)设计,它们内部包含非托管资源或句柄,默认序列化机制无法正确保存和恢复其完整状态,导致反序列化后对象不可用。
解决方案
需要借助Halcon自身提供的序列化API,手动实现HTuple和HObject的序列化/反序列化逻辑,下面分两种场景给出实现方案:
方案1:二进制序列化(基于ISerializable接口)
修改HalconConfig类,实现ISerializable接口,手动处理Halcon类型的读写:
using System.IO; using System.Runtime.Serialization; using HalconDotNet; [Serializable] public class HalconConfig : ISerializable { public HTuple mNumber; public HObject mImage; public HalconConfig() { mNumber = 6; HalconFunction.BitmapToHObject(Resources.TestImage, out mImage); } // 反序列化构造函数 protected HalconConfig(SerializationInfo info, StreamingContext context) { // 恢复HTuple var tupleBytes = (byte[])info.GetValue("mNumber", typeof(byte[])); using var ms = new MemoryStream(tupleBytes); mNumber = new HTuple(); mNumber.TupleDeserialize(ms); // 恢复HObject(以PNG格式为例) var imageBytes = (byte[])info.GetValue("mImage", typeof(byte[])); HOperatorSet.ReadImage(out mImage, "memory", imageBytes); } public void GetObjectData(SerializationInfo info, StreamingContext context) { // 序列化HTuple using var ms = new MemoryStream(); mNumber.TupleSerialize(ms); info.AddValue("mNumber", ms.ToArray()); // 序列化HObject(保存为PNG字节数组) HOperatorSet.WriteImage(mImage, "png", 0, out var imageBytes); info.AddValue("mImage", imageBytes); } }
使用方式保持你原来的BinaryFormatter代码即可,此时反序列化后的对象可正常使用。
方案2:Json序列化(基于Newtonsoft.Json自定义转换器)
如果偏好Json格式,可通过自定义Json转换器处理Halcon类型:
1. 编写自定义转换器
using HalconDotNet; using Newtonsoft.Json; using System; public class HTupleConverter : JsonConverter<HTuple> { public override HTuple ReadJson(JsonReader reader, Type objectType, HTuple existingValue, bool hasExistingValue, JsonSerializer serializer) { var tupleStr = reader.Value.ToString(); var tuple = new HTuple(); tuple.FromString(tupleStr); return tuple; } public override void WriteJson(JsonWriter writer, HTuple value, JsonSerializer serializer) { writer.WriteValue(value.TupleString()); } } public class HObjectConverter : JsonConverter<HObject> { public override HObject ReadJson(JsonReader reader, Type objectType, HObject existingValue, bool hasExistingValue, JsonSerializer serializer) { var base64Str = reader.Value.ToString(); var imageBytes = Convert.FromBase64String(base64Str); HOperatorSet.ReadImage(out var image, "memory", imageBytes); return image; } public override void WriteJson(JsonWriter writer, HObject value, JsonSerializer serializer) { HOperatorSet.WriteImage(value, "png", 0, out var imageBytes); writer.WriteValue(Convert.ToBase64String(imageBytes)); } }
2. 修改HalconConfig类并使用
using Newtonsoft.Json; public class HalconConfig { [JsonConverter(typeof(HTupleConverter))] public HTuple mNumber; [JsonConverter(typeof(HObjectConverter))] public HObject mImage; public HalconConfig() { mNumber = 6; HalconFunction.BitmapToHObject(Resources.TestImage, out mImage); } }
3. 序列化/反序列化代码
var _config1 = new HalconConfig(); // 序列化 var jsonContent = JsonConvert.SerializeObject(_config1); File.WriteAllText("./test.json", jsonContent); // 反序列化 var _config2 = JsonConvert.DeserializeObject<HalconConfig>(File.ReadAllText("./test.json")); BaseFunction.SendLog($"{_config2.mNumber}", LogLevel.Debug);
关键注意事项
- 确保使用的Halcon.NET版本支持
TupleSerialize/TupleDeserialize、WriteImage/ReadImage这些API; - 若HObject是多通道或特殊格式图像,可调整
WriteImage的格式参数(如改为"bmp"或"tiff"); - 序列化完成后,记得手动释放HObject资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Zeros遇见
相关产品推荐
相关产品推荐

