How to convert WMF to EMF+ with GdipConvertToEmfPlus without losing three-quarter of image?

点点圈 提交于 2020-01-17 02:27:11

问题


After converting WMF to EMF+ in order to get anti-aliased rendering, only the upper left quadrant of my WMF is included after conversion to EMF+.

Drawing the WMF (before conversion) with EnumerateMetafile works, but doesn't anti-alias, which is what I'm gunning for here.

Any ideas why three quarters of the image is lost on conversion?

The WMF was generated by AutoCAD LT and 32640x14586 pixels sized, with units/inch=1632.

The record types in the EMF (after conversion) are:

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

I've tried skipping SetPageTransform and SetClipRegion in the metafilecallback, and also scaling the graphics before, but nothing helps.

I'll see if I can share the original WMF for inspection.

See how the conversion is done here via this question: How to enable anti-aliasing when rendering WMF to BitMap in C#/WPF/WinForms?


回答1:


So, I had to scale the matrix of SetWorldTransform record by 0.75, then it's all ok??!

This is how my EnumerateMetafile call code looks, with the surrounding code, if anyone else happens upon this.

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

(Naming of the scaling parameter is intentional.)



来源:https://stackoverflow.com/questions/38071340/how-to-convert-wmf-to-emf-with-gdipconverttoemfplus-without-losing-three-quarte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!