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();
}
上一篇: Shell—编程100例