如何使用GdipConvertToEmfPlus将WMF转换为EMF+而不会丢失四分之三的图像

本文关键字:四分之三 图像 EMF+ GdipConvertToEmfPlus 何使用 WMF 转换 | 更新日期: 2023-09-27 17:52:46

将WMF转换为EMF+后,为了获得抗混叠渲染,转换为EMF+后仅包含我的WMF的左上象限。

用EnumerateMetafile绘制WMF(转换前)工作,但不抗别名,这是我在这里的目标。

你知道为什么四分之三的图像在转换时丢失了吗?

WMF由AutoCAD LT生成,尺寸为32640x14586像素,单位/英寸=1632。

EMF中的记录类型(转换后)为:

EmfMin
Header
SetAntiAliasMode
SetPixelOffsetMode
SetTextRenderingHint
MultiplyWorldTransform
Save
MultiplyWorldTransform
SetWorldTransform
BeginContainerNoParams
SetAntiAliasMode
SetPixelOffsetMode
SetTextRenderingHint
SetPageTransform
SetWorldTransform
SetWorldTransform
SetWorldTransform
SetWorldTransform
SetWorldTransform
Object
Object
DrawPath
...
SetClipRegion
EndContainer
Restore
SetWorldTransform
EndOfFile
EmfEof

我试过跳过SetPageTransform和SetClipRegion在元文件回调,也缩放图形之前,但没有帮助。

我看看是否可以分享WMF原件供检查。

看看这里的转换是如何通过这个问题完成的:如何在c#/WPF/WinForms中渲染WMF到位图时启用抗锯齿?

如何使用GdipConvertToEmfPlus将WMF转换为EMF+而不会丢失四分之三的图像

所以,我必须将SetWorldTransform记录的矩阵缩放0.75,然后就没事了??!

这是我的EnumerateMetafile调用代码看起来,与周围的代码,如果有人发生在这。

graphics.EnumerateMetafile(emfPlusMetaFile, new PointF(0, 0),
    (recordType, flags, dataSize, data, callbackData) =>
    {
        var dataArray = GetDataArray(data, dataSize);
        AdjustWorldTransformScale(recordType, dataArray, 0.75f);
        emfPlusMetaFile.PlayRecord(recordType, flags, dataSize, dataArray);
        return true;
    }
);

private static void AdjustWorldTransformScale(EmfPlusRecordType recordType, byte[] dataArray, float wtfScale)
{
    if (recordType == EmfPlusRecordType.SetWorldTransform)
    {
        using (var stream = new MemoryStream(dataArray))
        using (var reader = new BinaryReader(stream))
        using (var writer = new BinaryWriter(stream))
        {
            var m11 = reader.ReadSingle();
            var m12 = reader.ReadSingle();
            var m21 = reader.ReadSingle();
            var m22 = reader.ReadSingle();
            stream.Position = 0;
            writer.Write(m11*wtfScale);
            writer.Write(m12*wtfScale);
            writer.Write(m21*wtfScale);
            writer.Write(m22*wtfScale);                
        }
    }
}
private static byte[] GetDataArray(IntPtr data, int dataSize)
{
    if (data == IntPtr.Zero) return null;
    // Copy the unmanaged record to a managed byte buffer that can be used by PlayRecord.
    var dataArray = new byte[dataSize];
    Marshal.Copy(data, dataArray, 0, dataSize);
    return dataArray;
}

(缩放参数的命名是有意的)