Десериализация метафайла

У меня есть приложение, которое работает с расширенными метафайлами.

Я могу создать их, сохранить их на диск как.emf и загрузить их снова без проблем.

Я делаю это с помощью методов gdi32.dll и атрибута DLLImport.

Тем не менее, чтобы включить версионную сериализацию, я хочу сохранить метафайл в объекте вместе с другими данными.

По сути, это означает, что мне нужно сериализовать данные метафайла в виде байтового массива, а затем снова десериализовать его, чтобы восстановить метафайл.

Проблема, с которой я столкнулся, заключается в том, что десериализованные данные могут быть каким-то образом повреждены, поскольку метод, который я использую для восстановления метафайла, вызывает "Исключение допустимого параметра".

По крайней мере, формат пикселей и разрешения изменились.

Использование кода ниже.

 [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 (модель), после чего докладчик может получить к нему доступ для отображения.

    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);
        }

    }

Проблема в том, что сохранить на диск не удается. Если этот же метод используется для сохранения исходного метафайла до его сериализации, все в порядке. Таким образом, что-то происходит с данными во время сериализации / десериализации.

Действительно, если я проверю свойства метафайла в отладчике, то увижу, что ImageFlags, PropertyID, разрешение и пиксельные форматы меняются.

Исходный Format32bppRgb изменяется на Format32bppArgb

Исходное разрешение 81 изменяется на 96

Я трал хотя Google и ТАК, и это помогло мне получить это далеко, но я теперь застрял.

У кого-нибудь достаточно опыта работы с метафайлами / сериализацией, чтобы помочь..?

РЕДАКТИРОВАТЬ: Если я сериализовать / десериализовать байтовый массив напрямую (без встраивания в другой объект), я получаю ту же проблему.

0 ответов

Другие вопросы по тегам