You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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遇见

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:55:14