none
請問大大 .. 使用 Image 存成 EMF 的問題 RRS feed

解答

  • 你的 C.emf 應該是 png 格式。建議你用支援分辨格式的軟體解開來看看。

     

    也有可能是一個 EMF 崁入一個 BMP 圖檔,可以用 Visio / PowerPoint 崁入後,解開群組,若能解開群組,就是一個點陣檔崁入向量檔。

     

    我不知道你指的是哪段程式碼,因為那篇有滿多段落的,假設是最後一個回應時的程式碼:

    程式碼區塊

    Dim BitMap1 As New System.Drawing.Imaging.Metafile(stmMemory, ipHdc)

     

     

    這段已經指出產生 Metafile 了。

    使用上我通常用 MemoryStream ,這樣要直接輸出或是存成檔案都滿方便的,畢竟一個 EMF 通常都在 10 MB 以內,用 MemoryStream 暫存 EMF 不會太吃資源。

     

    EMF 與 WMF 的差異你可以看看這篇:

    [VBNET] 關於MetaFile

     

    .Net 是包裝 Windows API 的,所以可以回頭去看 Windows API ,EMF / WMF 只有差在建立 hDC 時,其他都一樣,所以回過頭來看 Metafile 的建構函式,只有兩個:

    Metafile 建構函式 (IntPtr, WmfPlaceableFileHeader)

    Metafile 建構函式 (IntPtr, WmfPlaceableFileHeader, Boolean)

     

    但是 WmfPlaceableFileHeader 額外檔頭的 WMF 是 Office 4.2 以後加入的特殊格式,不被 Windows API 直接支援。

     

    而 WMF 是 EMF 舊版,由於座標為 2 bytes 整數,亦即表示在 600 DPI 解析度下,最大長寬為 32768 / 600 / 2.54 = 21.5 cm ,一張 A4 約是 29 cm * 21 cm ,表示連一張 A4 大小都不到,所以我根本不考慮 WMF 格式,因為沒意義,要是碰上更高解析度的印表機,例如 1200 DPI 的,只剩下 10 cm 。

     

    我自己沒有特別處理 WMF ,.Net 直接另存 WMF 其實是 EMF ,用一些工具軟體也能看出來,然後去看 Metafile 建構函式,幾乎都是 EMF ,所以我自己是認為 .Net 內建類別新建、輸出只能處理 EMF ,WMF 應該是要自己呼叫 API 建立 hMF 的 DC,否則都是偽的。直接讀取 WMF 另存 WMF 才有可能,因為沒轉換到 EMF 。

     

    我自己在做這方面主要都是為了列印,所以達不到列印需求的 WMF 我在 .Net 並沒有很花時間在研究,以前在 VB5/6 則是直接呼叫 API 來處理,呼叫 API 就只差在起始 hMF 的建立:

     

    EMF:

    hMF = CreateEnhMetaFile(...)

     

    WMF:

    hMF = CreateMetaFile(...)

     

    而且那時候好的雷射印表及最高也不過是 600 DPI (HP LaserJet 4/5/6),所以那時才會支援 WMF 。

     

    將 EMF 另存為 WMF 在 API 上就更麻煩,要把一個個繪圖動作列舉出來,然後將 4 bytes 整數轉成 2 bytes 整數,還有部分繪圖動作在 WMF 上不支援,我自己沒有需求的前提下,沒打算搞這個。

    2007年10月2日 上午 03:38
    版主

所有回覆

  • 沒看到你前後的程式碼不確定,Metafile 類別不要轉型為 Image/Bitmap ,轉型後就變成只能存成點陣檔。

     

    你引用的那個連結我是用 Dim pic As Object 來承接。

     

    MS.ToArray 也可以直接得到 Byte() ,我不太知道你怎樣包裝,我自己是再包裝 MetaFile 類別,就可以直接輸出 Stream (從 MS) / Byte() / File 等。
    2007年10月1日 上午 08:20
    版主
  •  

    大大,我是直接使用你的程式,僅在 With Response 之前加上,下列這段程式碼

     

    '存成檔案的程式碼 --------------------------------------

    BitMap1.Save("C:\C.EMF", ImageFormat.Emf)

     

    Dim fs as FileStream = New FileStream("C:\D.EMF", FileMode.CreateNew)

    Dim BW as BinaryWriter = New BinaryWriter(fs)

    Dim DD as Byte() = stmMemory.ToArray()

    BW.Write(DD)

    BW.Close()

    fs.Close()

    '-------------------------------------------------------

     

    結果我發現使用 Window  預設的 "圖片和傳真檢視器" 來放大檢視 C.EMF 時,仍有鋸尺狀,但 D.EMF 不會。

     

    另外,讓我不能理解的是,大大的範例並沒有明顯的指定圖檔的格式,在產生 Metafile 時並不需要指定圖檔格式,僅在 Response 時指定 Content 為 image/emf。我直接將 stmMemory 資料存成檔案時,也不需要指定圖檔格式,使用 Metafile 來存成 EMF,卻仍是點陣圖,是不是只要補上 Metafile 就會變成向量圖?那 EMF 與 WMF 在 Metafile 上沒有差別嗎?如果我需要 WMF 格式又該怎麼作呢?

    2007年10月2日 上午 02:41
  • 你的 C.emf 應該是 png 格式。建議你用支援分辨格式的軟體解開來看看。

     

    也有可能是一個 EMF 崁入一個 BMP 圖檔,可以用 Visio / PowerPoint 崁入後,解開群組,若能解開群組,就是一個點陣檔崁入向量檔。

     

    我不知道你指的是哪段程式碼,因為那篇有滿多段落的,假設是最後一個回應時的程式碼:

    程式碼區塊

    Dim BitMap1 As New System.Drawing.Imaging.Metafile(stmMemory, ipHdc)

     

     

    這段已經指出產生 Metafile 了。

    使用上我通常用 MemoryStream ,這樣要直接輸出或是存成檔案都滿方便的,畢竟一個 EMF 通常都在 10 MB 以內,用 MemoryStream 暫存 EMF 不會太吃資源。

     

    EMF 與 WMF 的差異你可以看看這篇:

    [VBNET] 關於MetaFile

     

    .Net 是包裝 Windows API 的,所以可以回頭去看 Windows API ,EMF / WMF 只有差在建立 hDC 時,其他都一樣,所以回過頭來看 Metafile 的建構函式,只有兩個:

    Metafile 建構函式 (IntPtr, WmfPlaceableFileHeader)

    Metafile 建構函式 (IntPtr, WmfPlaceableFileHeader, Boolean)

     

    但是 WmfPlaceableFileHeader 額外檔頭的 WMF 是 Office 4.2 以後加入的特殊格式,不被 Windows API 直接支援。

     

    而 WMF 是 EMF 舊版,由於座標為 2 bytes 整數,亦即表示在 600 DPI 解析度下,最大長寬為 32768 / 600 / 2.54 = 21.5 cm ,一張 A4 約是 29 cm * 21 cm ,表示連一張 A4 大小都不到,所以我根本不考慮 WMF 格式,因為沒意義,要是碰上更高解析度的印表機,例如 1200 DPI 的,只剩下 10 cm 。

     

    我自己沒有特別處理 WMF ,.Net 直接另存 WMF 其實是 EMF ,用一些工具軟體也能看出來,然後去看 Metafile 建構函式,幾乎都是 EMF ,所以我自己是認為 .Net 內建類別新建、輸出只能處理 EMF ,WMF 應該是要自己呼叫 API 建立 hMF 的 DC,否則都是偽的。直接讀取 WMF 另存 WMF 才有可能,因為沒轉換到 EMF 。

     

    我自己在做這方面主要都是為了列印,所以達不到列印需求的 WMF 我在 .Net 並沒有很花時間在研究,以前在 VB5/6 則是直接呼叫 API 來處理,呼叫 API 就只差在起始 hMF 的建立:

     

    EMF:

    hMF = CreateEnhMetaFile(...)

     

    WMF:

    hMF = CreateMetaFile(...)

     

    而且那時候好的雷射印表及最高也不過是 600 DPI (HP LaserJet 4/5/6),所以那時才會支援 WMF 。

     

    將 EMF 另存為 WMF 在 API 上就更麻煩,要把一個個繪圖動作列舉出來,然後將 4 bytes 整數轉成 2 bytes 整數,還有部分繪圖動作在 WMF 上不支援,我自己沒有需求的前提下,沒打算搞這個。

    2007年10月2日 上午 03:38
    版主