zoukankan      html  css  js  c++  java
  • 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();
    }

  • 相关阅读:
    负载、系统oracle 系统调优之 利用CPUby小雨
    进程、检查oracle 性能调优 解决CPU问题by小雨
    数据、保存【sqlite】——使用记录by小雨
    MySQL中间变量的用法by小雨
    函数、返回Sql Server常用函数之统计、算数、字符串函数by小雨
    数据库、实体数据库设计原则by小雨
    查看、设置centos下在线安装配置mysqlby小雨
    重启、无效Oracle使用raw via lvmby小雨
    总线、虚拟机VMware 创建虚拟机的磁盘操作by小雨
    驱动、数据库Java HIVE 使用Jdbc连接Hiveby小雨
  • 原文地址:https://www.cnblogs.com/nihaolican/p/11865292.html
Copyright © 2011-2022 走看看