C# 矢量图EMF 总结

网友投稿 785 2022-09-11

C# 矢量图EMF 总结

C# 矢量图EMF 总结

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

个人站点:https://i-blogs.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、非托管调用代码

///

/// 获取矢量图的byte

///

///

///

///

///

[DllImport("gdi32.dll")]

public static extern uint GetEnhMetaFileBits(IntPtr hemf, uint cbBuffer, byte[] lpbBuffer);

///

/// byte转换矢量图

///

///

///

///

[DllImport("gdi32.dll")]

public static extern IntPtr SetEnhMetaFileBits(uint cbBuffer, byte[] lpBuffer);

///

/// 删除矢量图

///

///

///

[DllImport("gdi32.dll")]

public static extern bool DeleteEnhMetaFile(IntPtr hemf);

///

/// Copy EMF to file

///

/// Handle to EMF

/// File

///

[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();

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:MDT8456 部署Windows 10 21H2系列 (一): 基础篇—环境准备及安装
下一篇:VMWare虚拟机启动不了有个叉叉的解决办法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~