У меня есть приложение, которое работает с Расширенными метафайлами .
Я могу создать их, сохранить их на диск как .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;
}
В этом пунктеnt 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, разрешение и пиксельные форматы.
Исходный формат32bppRgbизменения в Format32bppArgb
Исходное разрешение 81 изменяется на 96
Я трахал через Google и SO, и это помогло мне зайти так далеко, но я застрял.
Делает что-нибудьу одного достаточно опыта работы с метафайлами / сериализацией, чтобы помочь ..?
РЕДАКТИРОВАТЬ: Если я сериализую / десериализую байтовый массив напрямую (без встраивания в другой объект), я получаю ту же проблему.