0

在将 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 以供检查。

通过这个问题了解转换是如何在此处完成的: How to enable anti-aliasing when rendering WMF to BitMap in C#/WPF/WinForms?

4

1 回答 1

0

所以,我必须将 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;
}

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

于 2016-06-28T09:03:56.313 回答