Metafile deamination

I have an application that works with Enhanced Metafiles .

I can create them, save them to disk as .emf and load them again without any problems.

I do this using the gdi32.dll methods and the DLLImport attribute .

However, to enable Version Tolerant Serialization I want to save the metafile in the object along with other data.

This essentially means that I need to serialize the metafile data as an array of bytes, and then deserialize it again to restore the metafile.

The problem is that the deserialized data will not look right, because the method that I use to restore Metafile calls the "Invalid parameter".

At least the format and resolution of the pixels have changed.

Use the code below.

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

The application creates a metafile image and passes it to the method below.

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

At this point, the dataArray is inserted into the object and serialized using the BinaryFormatter.

Then, the saved file is again deserialized using BinaryFormatter and the dataArray extracted from the object.

Then, a DataArray is used to restore the original metafile using the following method.

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

The recovered metafile is then saved on disk as .emf (Model), after which it can be accessed by the Presenter application for display.

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

The problem is that a disk failure crashes. If the same method is used to save the original metafile until it is serialized, everything is in order. Thus, something happens to the data during serialization / deserialization.

Indeed, if I check the Metafile properties in the debugger, I see that ImageFlags, PropertyID, resolution and pixel formats are changing.

Source format Format32bppRgb changes to Format32bppArgb

Original Resolution 81 Changes to 96

I trawled, although google and SO, and it helped me get this far, but Im now stuck.

Does anyone have enough experience with Metafiles / serialization to help ..?

EDIT: If I serialize / deserialize an array of bytes directly (without embedding in another object), I get the same problem.

+4
source share

Source: https://habr.com/ru/post/1306264/


All Articles