欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

本以為非常簡單,我快速給出了解決方案:

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)友告訴我,這是錯誤的:

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

這是怎么回事呢?

原因

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

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

不理解這樣設計的原因,不支持應該拋出異常吧?!

實現(xiàn)

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

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

創(chuàng)建實例失敗

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

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

結(jié)果報了個通用異常,完全沒有指導意義:

只好反編譯代碼查錯。

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

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

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

查看其他構(gòu)造函數(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);
}

也就是說,這個 API 可以創(chuàng)建 EMF 文件??磥砜梢杂?。

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

于是,實現(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);
        }
    }
}

生成的確實是矢量圖形文件:

繪制位置錯誤

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

再次查找構(gòu)造函數(shù),發(fā)現(xiàn)可以傳遞Rectangle參數(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é)論

后來發(fā)現(xiàn),生成的圖片實際是375 x 375像素,這應該是因為我的顯示屬性設置了縮放的原因(375 / 300 = 1.25):

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

相關文章

最新評論