反序列化元文件

时间:2010-04-07 16:04:10

标签: c# serialization gdi+ metafile

我有一个适用于Enhanced Metafiles的应用程序。

我能够创建它们,将它们作为.emf保存到磁盘并再次加载它们没问题。

我是通过使用gdi32.dll方法和DLLImport attribute

来实现的

但是,要启用Version Tolerant Serialization,我想将元文件与其他数据一起保存在对象中。

这实质上意味着我需要将元文件数据序列化为字节数组,然后再次反序列化以重构元文件。

我遇到的问题是反序列化的数据似乎在某种程度上被破坏了,因为我用来重建元文件的方法引发了“参数无效异常”。

至少像素格式和分辨率已经改变。

代码使用如下。

 [DllImport("gdi32.dll")]
    public static extern uint GetEnhMetaFileBits(IntPtr hemf, uint cbBuffer, byte[] lpbBuffer);
    [DllImport("gdi32.dll")]
    public static extern IntPtr SetEnhMetaFileBits(uint cbBuffer, byte[] lpBuffer);
    [DllImport("gdi32.dll")]
    public static extern bool DeleteEnhMetaFile(IntPtr hemf);

应用程序创建一个图元文件图像并将其传递给下面的方法。

    private byte[] ConvertMetaFileToByteArray(Image image)
    {
        byte[] dataArray = null;

        Metafile mf = (Metafile)image;

        IntPtr enhMetafileHandle = mf.GetHenhmetafile();

        uint bufferSize = GetEnhMetaFileBits(enhMetafileHandle, 0, null);


        if (enhMetafileHandle != IntPtr.Zero)
        {
            dataArray = new byte[bufferSize];

            GetEnhMetaFileBits(enhMetafileHandle, bufferSize, dataArray);
        }

        DeleteEnhMetaFile(enhMetafileHandle);

        return dataArray;
    }

此时,dataArray被插入到一个对象中并使用BinaryFormatter进行序列化。

然后使用BinaryFormatter再次反序列化保存的文件,并从对象中检索dataArray。

然后使用dataArray使用以下方法重建原始图元文件。

    public static Image ConvertByteArrayToMetafile(byte[] data)
    {
        Metafile mf = null;

        try
        {
            IntPtr hemf = SetEnhMetaFileBits((uint)data.Length, data);

            mf = new Metafile(hemf, true);

        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message);
        }

        return (Image)mf;
    }

然后将重建的元文件保存为.emf(模型)保存到磁盘,此时Presenter可以访问它以供显示。

    private static void SaveFile(Image image, String filepath)
    {
        try
        {
            byte[] buffer = ConvertMetafileToByteArray(image);

            File.WriteAllBytes(filepath, buffer); //will overwrite file if it exists
        }
        catch (Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message);
        }

    }

问题是保存到磁盘失败。如果在序列化之前使用相同的方法保存原始的Metafile,一切正常。因此,在序列化/反序列化期间,数据会发生一些事情。

的确,如果我在调试器中检查元文件属性,我可以看到ImageFlags,PropertyID,分辨率和像素格式发生了变化。

原始Format32bppRgb更改为Format32bppArgb

原始分辨率81变为96

我已经在google和SO上拖网了,这帮助我走到了尽头,但我现在卡住了。

是否有人有足够的元文件/序列化经验来帮助..?

编辑:如果我直接序列化/反序列化字节数组(没有嵌入另一个对象),我会遇到同样的问题。

0 个答案:

没有答案