亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#生成EMF矢量圖形文件示例詳解

 更新時(shí)間:2022年05月20日 09:02:13   作者:MyIO  
這篇文章主要為大家介紹了C#?生成?EMF矢量圖形文件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

公眾號(hào)上有網(wǎng)友詢問(wèn)我如何生成 EMF 文件的問(wèn)題:

本以為非常簡(jiǎn)單,我快速給出了解決方案:

var bitmap = new Bitmap(640, 480);
var g = Graphics.FromImage(bitmap);
g.DrawString("My IO", new Font(FontFamily.GenericSerif, 10), Brushes.Blue, 100, 100);
bitmap.Save("MyIO.emf",ImageFormat.Emf);

結(jié)果,網(wǎng)友告訴我,這是錯(cuò)誤的:

用編輯器查看文件內(nèi)容,發(fā)現(xiàn)實(shí)際生成的是PNG格式文件:

這是怎么回事呢?

原因

在官方文檔上找到這樣一段話:

當(dāng)使用Save此方法將圖形圖像另存為Windows元文件格式 (WMF) 或增強(qiáng)的圖元文件格式 (EMF) 文件時(shí),生成的文件將改為保存為可移植網(wǎng)絡(luò)圖形 (PNG) 文件。發(fā)生此行為是因?yàn)?NET Framework的GDI+組件沒有可用于將文件另存為 .wmf 或 .emf 文件的編碼器。

不理解這樣設(shè)計(jì)的原因,不支持應(yīng)該拋出異常吧?!

實(shí)現(xiàn)

不過(guò)還好,從文檔上我們也找到了解決方案,那就是使用Metafile類。

可是在實(shí)現(xiàn)時(shí),又踩了不少坑。

創(chuàng)建實(shí)例失敗

按照示例代碼,使用文件名創(chuàng)建實(shí)例:

var metafile = new Metafile("MyIO.emf");

結(jié)果報(bào)了個(gè)通用異常,完全沒有指導(dǎo)意義:

只好反編譯代碼查錯(cuò)。

發(fā)現(xiàn),底層實(shí)現(xiàn)使用的GdipCreateMetafileFromFileAPI:

public Metafile(string filename)
{
 Path.GetFullPath(filename);
 SafeNativeMethods.Gdip.CheckStatus(SafeNativeMethods.Gdip.GdipCreateMetafileFromFile(filename, out IntPtr metafile));
 SetNativeImage(metafile);
}

也就是說(shuō),參數(shù)必須是一個(gè)已存在的 EMF 文件名。

查看其他構(gòu)造函數(shù)的實(shí)現(xiàn),發(fā)現(xiàn)傳遞referenceHdc的構(gòu)造函數(shù)使用的是GdipRecordMetafileFileNameAPI:

public Metafile(string fileName, IntPtr referenceHdc, EmfType type, string? description)
{
 Path.GetFullPath(fileName);
 SafeNativeMethods.Gdip.CheckStatus(SafeNativeMethods.Gdip.GdipRecordMetafileFileName(fileName, referenceHdc, type, IntPtr.Zero, MetafileFrameUnit.GdiCompatible, description, out IntPtr metafile));
 SetNativeImage(metafile);
}

也就是說(shuō),這個(gè) API 可以創(chuàng)建 EMF 文件??磥?lái)可以用。

而referenceHdc可以使用Graphics.GetHdc()得到。

于是,實(shí)現(xiàn)代碼如下:

using (Graphics g1 = Graphics.FromHwnd(IntPtr.Zero))
{
    using (var metafile = new Metafile("MyIO.emf", g1.GetHdc()))
    {
        using (Graphics g2 = Graphics.FromImage(metafile))
        { 
            g2.DrawString("My IO", new Font(FontFamily.GenericSerif, 10), Brushes.Blue, 100, 100);
            g2.DrawString("My IO", new Font(FontFamily.GenericSerif, 10), Brushes.Blue, 200, 200);
        }
    }
}

生成的確實(shí)是矢量圖形文件:

繪制位置錯(cuò)誤

可以明顯看到,第一個(gè)My IO繪制的位置是錯(cuò)誤的,繪制到了左上角,而不是(100, 100)。

再次查找構(gòu)造函數(shù),發(fā)現(xiàn)可以傳遞Rectangle參數(shù):

修改實(shí)現(xiàn)代碼如下:

using (Graphics g1 = Graphics.FromHwnd(IntPtr.Zero))
{
    using (var metafile = new Metafile("MyIO.emf", g1.GetHdc(), new Rectangle(0, 0, 300, 300), MetafileFrameUnit.Pixel))
    {
        using (Graphics g2 = Graphics.FromImage(metafile))
        {
            g2.DrawString("My IO", new Font(FontFamily.GenericSerif, 10), Brushes.Blue, 100, 100);
            g2.DrawString("My IO", new Font(FontFamily.GenericSerif, 10), Brushes.Blue, 200, 200);
        }
    }
}

這次總算成功了:

結(jié)論

后來(lái)發(fā)現(xiàn),生成的圖片實(shí)際是375 x 375像素,這應(yīng)該是因?yàn)槲业娘@示屬性設(shè)置了縮放的原因(375 / 300 = 1.25):

以上就是C#生成EMF矢量圖形文件示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C#生成EMF矢量圖形文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論