如何使用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到位图时启用抗锯齿?
所以,我必须将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;
}
(缩放参数的命名是有意的)