C# 矢量图EMF 总结

Posted nihaolican

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 矢量图EMF 总结相关的知识,希望对你有一定的参考价值。

个人知识记录、如果有用请点赞,否则勿喷、忽略。

个人站点:https://i.cnblogs.com/EditPosts.aspx?opt=1

注意:句柄的操作
1、创建 代码如下:


Metafile metafile;
using(Graphics offScreenGraphics = Graphics.FromHwndInternal(IntPtr.Zero))
{
IntPtr hDC = offScreenGraphics.GetHdc();
metafile = new Metafile(hDC,
new Rectangle(0, 0, metafileWidth, metafileHeight),
MetafileFrameUnit.Pixel,
EmfType.EmfPlusOnly);
offScreenGraphics.ReleaseHdc();
}

return metafile;

2、GDI Graphics 创建

var graphics = Graphics.FromImage(metafile); //也可以使用句柄

//有时大小可能设置的不好使 需进行特殊处理
var width=height=0;
graphics.SetClip(new RectangleF(0, 0, width, height));

3、非托管调用代码

/// <summary>
/// 获取矢量图的byte
/// </summary>
/// <param name="hemf"></param>
/// <param name="cbBuffer"></param>
/// <param name="lpbBuffer"></param>
/// <returns></returns>
[DllImport("gdi32.dll")]
public static extern uint GetEnhMetaFileBits(IntPtr hemf, uint cbBuffer, byte[] lpbBuffer);
/// <summary>
/// byte转换矢量图
/// </summary>
/// <param name="cbBuffer"></param>
/// <param name="lpBuffer"></param>
/// <returns></returns>
[DllImport("gdi32.dll")]
public static extern IntPtr SetEnhMetaFileBits(uint cbBuffer, byte[] lpBuffer);
/// <summary>
/// 删除矢量图
/// </summary>
/// <param name="hemf"></param>
/// <returns></returns>
[DllImport("gdi32.dll")]
public static extern bool DeleteEnhMetaFile(IntPtr hemf);

/// <summary>
/// Copy EMF to file
/// </summary>
/// <param name="hemfSrc">Handle to EMF</param>
/// <param name="lpszFile">File</param>
/// <returns></returns>
[DllImport("gdi32.dll")]
private static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc, string lpszFile);

4、矢量图 转换 byte[]

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

5、byte[] 转换 矢量图
public static Image ConvertByteArrayToMetafile(byte[] data)
{
Metafile mf = null;
IntPtr hemf = SetEnhMetaFileBits((uint)data.Length, data);
mf = new Metafile(hemf, true);
//DeleteEnhMetaFile(hemf); //如若后续对图像进行操作不能进行删除句柄
return (Image)mf;
}


6、矢量图保存

public static void SaveMetafile(Metafile file, string emfName)
{
//MetafileHeader metafileHeader = file.GetMetafileHeader(); //这句话可要可不要
IntPtr iptrMetafileHandle = file.GetHenhmetafile();
CopyEnhMetaFile(iptrMetafileHandle, emfName);
DeleteEnhMetaFile(iptrMetafileHandle);
}

7、转换base64 字符
var m = (Metafile)Metafile.FromFile(@"EMF.emf"); //加载矢量图
var by = ConvertMetaFileToByteArray(m); //转换数组
var ls = Convert.ToBase64String(by); //转字符串

8、base64转 byte[]

var bt = Convert.FromBase64String(ls);

9、图像的通过字符生长之后、可保存操作、不能进行绘制操作、这时需要进行 创建一个新的对象接受这个生成对象、然后操作
var imz = (Metafile)ConvertByteArrayToMetafile(bt);
var jbhtr = imz.GetHenhmetafile();
Metafile mmmmm = new Metafile(jbhtr, true); //new 新对象接收

10、矢量图的结构播放主要使用:EnumerateMetafileProc 代码如下

public partial class MetafilePlayRecord : Form
{
private Metafile metafile1;
private Graphics.EnumerateMetafileProc metafileDelegate;
public MetafilePlayRecord(Metafile metafile )
{
InitializeComponent();
metafile1 = metafile;
metafileDelegate = new Graphics.EnumerateMetafileProc(MetafileCallback);
}

private bool MetafileCallback(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData)
{
byte[] dataArray = null;
if (data != IntPtr.Zero)
{

dataArray = new byte[dataSize];
Marshal.Copy(data, dataArray, 0, dataSize);
//GdipComment
metafile1.PlayRecord(recordType, flags, dataSize, dataArray);
switch (recordType) //记录类型
{

case EmfPlusRecordType.Object: //对象
case EmfPlusRecordType.DrawLines: //线
case EmfPlusRecordType.SetPageTransform: //设置页变换
break;
}
}
Console.WriteLine(recordType.ToString());
return true;
}

protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.EnumerateMetafile(metafile1, destPoint, metafileDelegate);

}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
metafile1.Dispose();
}

以上是关于C# 矢量图EMF 总结的主要内容,如果未能解决你的问题,请参考以下文章

C#中如何生成矢量图

bmp,jpg,png,tif,wmf,emf与eps图片格式转换

C#操作SVG矢量图-nuget库svg

C#操作SVG矢量图-nuget库svg

多种图像格式相互转换工具

C#读取矢量栅格文件