C# 矢量图EMF 总结

2022-10-13

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

个人站点: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 总结.doc》

下载本文的Word格式文档,以方便收藏与打印。