none
請問大大... METAFILE - EMF 檔的問題... 弄好久了. 實在不知道怎弄... RRS feed

  • 問題

  • 附程式碼...

    不知道該怎改寫...  才能弄出EMF檔...

    PS : http://tlcheng.twbbs.org/aspx/Tools/Count/FontEnum.aspx 這是鄭老大的程式....

    發現到所產生的文字. 都能完全符合整的版面大小... 不知道是怎弄的...

    希望能得到解答... 感激~

     

     

    <%@ Page Language="VB" Debug="true" ContentType="image/png"%>
    <%@ Import Namespace="System.Drawing" %>
    <%@ Import Namespace="System.Drawing.Text" %>
    <%@ Import Namespace="System.Drawing.Imaging" %>
    <%@ Import Namespace="System.Drawing.Drawing2D" %>
    <%@ Import Namespace="System.Web.UI.Page" %>
    <%@ Import Namespace="NZlib.GZip" %>

    <script language=vb runat=server id="modResponseFile">
    Sub Page_Load(Sender As Object, E As EventArgs)
        Dim stmMemory As New System.IO.MemoryStream
        Dim BitMap1 As New Bitmap(800, 400,System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        Dim g As System.Drawing.Graphics  = System.Drawing.Graphics.FromImage(BitMap1) 

        g.Clear(Color.FromArgb(0,255,255,255))
        Dim blueBrush As New SolidBrush(Color.Transparent)

        Dim F As New System.Drawing.Font("中國龍海報體", 140)
        Dim b As New System.Drawing.SolidBrush(Color.Red)
        g.DrawString("這是測試", F,new SolidBrush(Color.RED), 0, 0)


        Response.ContentType = "image/png"
        BitMap1.Save(stmMemory, System.Drawing.Imaging.ImageFormat.png)
        stmMemory.WriteTo(Response.OutputStream)

    Dim objBmp As System.Drawing.Image = System.Drawing.Image.FromStream(stmMemory)


       
    End SUB
    </script>

    2007年6月10日 下午 08:07

解答

  • 你的程式碼改成這樣:

    程式碼

     

    <%@ Page Language="VB" Debug="true" ContentType="image/x-emf"%>

    <%@ Import Namespace="System.Drawing" %>

    <%@ Import Namespace="System.Drawing.Text" %>

    <%@ Import Namespace="System.Drawing.Imaging" %>

    <%@ Import Namespace="System.Drawing.Drawing2D" %>

    <%@ Import Namespace="System.Web.UI.Page" %>

    <script language=vb runat=server id="modResponseFile">

         Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs)

              ' ------------------------------------Metafile 宣告

              Dim bmp As New System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

              Dim grfx As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)

              Dim ipHdc As IntPtr = grfx.GetHdc()

     

              Dim stmMemory As New IO.MemoryStream

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

             

              grfx.ReleaseHdc(ipHdc)

              grfx.Dispose()

              bmp.Dispose()

     

              grfx = System.Drawing.Graphics.FromImage(BitMap1)

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

     

              grfx.Clear(Color.FromArgb(0, 255, 255, 255))

              Dim blueBrush As New SolidBrush(Color.Transparent)

     

              Dim F As New System.Drawing.Font("標楷體", 140)

              Dim b As New System.Drawing.SolidBrush(Color.Red)

              grfx.DrawString("這是測試", F, New SolidBrush(Color.Red), 0, 0)

              grfx.Dispose()

     

              With Response

                   .AddHeader("Content-disposition", "image/emf")

                   .ContentType = "attachment; filename=test.emf"

                   .BinaryWrite(stmMemory.ToArray)

                   .End()

              End With

         End Sub

    </script>

     

    我改的用不同底色標記,其中淺綠色部分考量節省資源替換 g 為 grfx ,淺紫色的是重要結束繪圖,不可省略,省略的話 MemoryStream 會鎖住。

     

    即時繪製結果(長期將移除):

    2007年6月11日 下午 04:05
    版主

所有回覆

  • 昨天有在其他地方先請你看一下:

    微軟官方 MSDN 討論區已有些既有討論,可透過搜尋功能搜尋 MetaFile 部份內容:

     
    不知道你看過沒?請先看過後,若還不清楚 EMF 產生方式再依據你實做的過程提出討論。既有討論也包含 EMF 的中文參考書籍說明。
     
    比如說裡面有提到下面這段話,討論內容也有簡單畫線的程式碼:

    自己畫的 MetaFile 請透過 New System.Drawing.Imaging.MetaFile(...) 來建立。

    再用 System.Drawing.Graphics.FromImage(MetaFile) 就可以建立 Graphics ,剩下來的跟一般繪圖一樣。


    所謂的「剩下來的跟一般繪圖一樣」,就是指跟在 bitmap 上用 Graphics 畫圖是一樣的,所以昨天回你那邊原始碼包含:

    http://forums.microsoft.com/MSDN-CHT/Search/Search.aspx?words=MetaFile&localechoice=31748&SiteID=14&searchscope=allforums

     
    不知道你看過沒?請先看過後,若還不清楚 EMF 產生方式再依據你實做的過程提出討論。既有討論也包含 EMF 的中文參考書籍說明。
     
    比如說裡面有提到下面這段話,討論內容也有簡單畫線的程式碼:

    自己畫的 MetaFile 請透過 New System.Drawing.Imaging.MetaFile(...) 來建立。

    再用 System.Drawing.Graphics.FromImage(MetaFile) 就可以建立 Graphics ,剩下來的跟一般繪圖一樣。


    所謂的「剩下來的跟一般繪圖一樣」,就是指跟在 bitmap 上用 Graphics 畫圖是一樣的,所以昨天回你那邊原始碼包含:

    程式碼

    Select Case LCase(strExtName)

         Case "emf", "wmf"

              Dim emf As New cMetaFile

              emf.CreatePictureGraphics()

              grfx = emf.MyCreateMetaFileGraphics()

              pic = emf

         Case Else

              bmp = New System.Drawing.Bitmap(boxWidth, boxHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

              grfx = System.Drawing.Graphics.FromImage(bmp)

              pic = bmp

    End Select

     

    而後面的程式碼就只處理 grfx 跟 pic ,只有差在一開始兩類的圖形宣告不同而已。

     
     註:
    cMetaFile 是我早先不熟 VBNET 時開發的東西,裡面整合我自己的宣告,沒有直接繼承 MetaFile 類別來擴充功能,也沒依據 VSNET 建議的命名規則取名,而是要啥寫啥的類別(VB6 的類別寫法),所以我自己打算廢掉重新開發個 MetaFileEx,繼承 MetaFile 可以省很多工,所以待報廢的類別也不打算發表在 http://tlcheng.twbbs.org/TLCheng/Net/NetList.aspx ,你可以用
    程式碼
    Dim ms As New IO.MemoryStream
    Dim emf As New System.Drawing.Imaging.MetaFile(ms)
    grfx = System.Drawing.Graphics.FromImage(emf)

     

    來取代上面使用 cMetaFile 的部份。

     
    關於最佳大小部份:
    點陣檔是要建兩次 bitmap 物件,第一次建立後,用 Graphics.MeasureString 去量測大小後,再依這個大小重新建立 bitmap 。昨天回你那邊貼的原始碼就包含這部份,上面那段轉貼的 bmp = New ... 就是用在第二次建立。
     
    EMF 本身會自動決定最佳大小,你畫多少用多少,可以不用管大小問題。若要強制指定大小的話,我自己是畫好後,用 DrawImage 畫到另一個空白的 EMF ,來決定裁減框的大小,或是建立 MetaFile 時,就指定 Size ,各有用途,當然也可以考慮用 Graphics 內的世界座標轉換去轉,不過那個會造成字型都受影響,基本上我都自建比例轉換,不透過那個轉,我現在自己正在構建的向量繪圖,就是從 PointD / SizeD / RectangleD 開始重新來,依據 PointF/SizeF/RectangleF 的介面來構建,因為我在顯示圖形前的座標系統要用倍精度,.Net 只有 Integer / Single。
    2007年6月11日 上午 01:53
    版主
  • ?

    看到文字重複本來是要用編輯模式刪,可是編輯模式進去,原文正常,有點怪異。

    2007年6月11日 上午 01:55
    版主
  • Dim emf As New cMetaFile

    請問這段... 應該是自訂的吧?

    那這段內容是是???

    2007年6月11日 上午 04:09
  • 上面回覆不是寫了嗎?


    你可以用

    程式碼
    Dim ms As New IO.MemoryStream
    Dim emf As New System.Drawing.Imaging.MetaFile(ms)
    grfx = System.Drawing.Graphics.FromImage(emf)

     

    來取代上面使用 cMetaFile 的部份。
    2007年6月11日 上午 04:21
    版主
  • 喔...... 我試試看..

    不好意思... 那我想另外請教您個問題...

    就是您的範例網站中... 所產生的文字圖中...  可以控制自有多大然後畫板就跟著放大....  請問您這個功能是怎完成的..  謝謝您~

     

    2007年6月11日 上午 06:50
  • 老大,拜託回文看仔細好嗎?你兩篇回文問的,在上面在一開始回覆時就一起都回了...

    上面回的關於圖檔大小的部份引用如下:


    關於最佳大小部份:
    點陣檔是要建兩次 bitmap 物件,第一次建立後,用 Graphics.MeasureString 去量測大小後,再依這個大小重新建立 bitmap 。昨天回你那邊貼的原始碼就包含這部份,上面那段轉貼的 bmp = New ... 就是用在第二次建立。
     
    EMF 本身會自動決定最佳大小,你畫多少用多少,可以不用管大小問題。若要強制指定大小的話,我自己是畫好後,用 DrawImage 畫到另一個空白的 EMF ,來決定裁減框的大小,或是建立 MetaFile 時,就指定 Size ,各有用途
    2007年6月11日 上午 07:14
    版主
  • 不好意思..

    因為 .NET 真的不是很熟析..

    語法上的使用... 很不習慣..

    因為我想要利用 .NET 的功能來補足 ASP 的不足.....  所以會部份用到 .NET 的資源...

    不過還是謝謝您....  我會再試試看...  有問題在請教您了~ 感恩~

    2007年6月11日 上午 07:41
  • 璉璉大大..

    我用了您提供的語法..  改了之後... 發生錯誤...... 如下..

     

    在 GDI+ 中發生泛型錯誤。

       行 12:     Dim stmMemory As New System.IO.MemoryStream
    行 13:     Dim BitMap1 As New System.Drawing.Imaging.MetaFile(stmMemory)
    行 14:     dim g = System.Drawing.Graphics.FromImage(BitMap1)

     

    請問這是.... 怎回事呢???

     

    感恩.

    2007年6月11日 上午 08:55
  • 璉連大大 ....  救命啊....

    您看一下錯誤訊息~

     

    '/' 應用程式中發生伺服器錯誤。

    在 GDI+ 中發生泛型錯誤。

    描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。

    例外詳細資訊: System.Runtime.InteropServices.ExternalException: 在 GDI+ 中發生泛型錯誤。

    原始程式錯誤:

    行 10: Sub Page_Load(Sender As Object, E As EventArgs)
    行 11: Dim ms As New IO.MemoryStream
    行 12: Dim emf As New System.Drawing.Imaging.MetaFile(ms)
    行 13: DIM grfx = System.Drawing.Graphics.FromImage(emf)
    行 14:     

    原始程式檔: D:\InterNet Floder\wwwroot\HISTORY\A09-TEST.aspx    行: 12

    堆疊追蹤:

    [ExternalException (0x80004005): 在 GDI+ 中發生泛型錯誤。]
       System.Drawing.Imaging.Metafile..ctor(Stream stream) +177686
       ASP.a09_test_aspx.Page_Load(Object Sender, EventArgs E) in D:\InterNet Floder\wwwroot\HISTORY\A09-TEST.aspx:12
       System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
       System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
       System.Web.UI.Control.OnLoad(EventArgs e) +99
       System.Web.UI.Control.LoadRecursive() +47
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061
    


    版本資訊: Microsoft .NET Framework 版本:2.0.50727.42; ASP.NET 版本:2.0
    2007年6月11日 上午 09:20
  • 唔~

    Dim BitMap1 As New System.Drawing.Imaging.MetaFile(stmMemory)

    是用在 MemoryStream 已有 EMF 直接抽出的方式。

     

    若要新建記憶體中的 EMF 範例如下:

    Code Snippet

    Dim bmp As New System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

    Dim grfx As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)

    Dim ipHdc As IntPtr = grfx.GetHdc()

    Dim ms As New IO.MemoryStream

    Dim emf As New System.Drawing.Imaging.Metafile(ms, ipHdc)

    'Dim emf As New System.Drawing.Imaging.Metafile(ms, ipHdc, New Drawing.Rectangle(0, 0, 201, 201), Imaging.MetafileFrameUnit.Pixel)

     

    grfx.ReleaseHdc(ipHdc)

    grfx.Dispose()

    bmp.Dispose()

     

    grfx = System.Drawing.Graphics.FromImage(emf)

    grfx.DrawLine(System.Drawing.Pens.Blue, 0, 0, 200, 200)

    grfx.Dispose()

     

    With Response

         .AddHeader("Content-disposition", "image/emf")

         .ContentType = "attachment; filename=test.emf"

         .BinaryWrite(ms.ToArray)

         .End()

    End With

     

    強制指定大小的宣告如註解列。

     

    描繪的結果如下(上面程式碼建立的網頁圖檔位於測試目錄內,未來可能會移除):

    2007年6月11日 上午 10:18
    版主
  • 還是有問題.....

    請大大幫忙看一下...  我是否哪邊改錯了..

     

    <%@ Page Language="VB" Debug="true" ContentType="image/x-emf"%>
    <%@ Import Namespace="System.Drawing" %>
    <%@ Import Namespace="System.Drawing.Text" %>
    <%@ Import Namespace="System.Drawing.Imaging" %>
    <%@ Import Namespace="System.Drawing.Drawing2D" %>
    <%@ Import Namespace="System.Web.UI.Page" %>
    <%@ Import Namespace="NZlib.GZip" %>

    <script language=vb runat=server id="modResponseFile">
    Sub Page_Load(Sender As Object, E As EventArgs)
        ' ------------------------------------Metafile 宣告
        Dim bmp As New System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        Dim grfx As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
        Dim ipHdc As IntPtr = grfx.GetHdc()

        Dim stmMemory As New IO.MemoryStream
        Dim BitMap1 As New System.Drawing.Imaging.MetaFile(stmMemory,ipHdc)
        dim g = System.Drawing.Graphics.FromImage(BitMap1)
        '---------------------------------------------------
        'Dim stmMemory As New System.IO.MemoryStream
        'Dim BitMap1 As New Bitmap(800, 400,System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        'Dim g As System.Drawing.Graphics  = System.Drawing.Graphics.FromImage(BitMap1) 

        g.Clear(Color.FromArgb(0,255,255,255))
        Dim blueBrush As New SolidBrush(Color.Transparent)

        Dim F As New System.Drawing.Font("中國龍海報體", 140)
        Dim b As New System.Drawing.SolidBrush(Color.Red)
        g.DrawString("這是測試", F,new SolidBrush(Color.RED), 0, 0)


        'Response.ContentType = "image/emf"
        'BitMap1.Save(stmMemory, System.Drawing.Imaging.ImageFormat.emf)
        'stmMemory.WriteTo(Response.OutputStream)

        With Response
             .AddHeader("Content-disposition", "image/emf")
             .ContentType = "attachment; filename=test.emf"
             .BinaryWrite(stmMemory.toArray)
             .End()
        End With
    End SUB
    </script>

     

     

    描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。

    例外詳細資訊: System.ArgumentOutOfRangeException: 指定的引數超出有效值的範圍。
    參數名稱: offset

    原始程式錯誤:

    行 37:      .AddHeader("Content-disposition", "image/emf")
    行 38:      .ContentType = "attachment; filename=test.emf"
    行 39:      .BinaryWrite(stmMemory.toArray)
    行 40:      .End()
    行 41: End With

    原始程式檔: D:\InterNet Floder\wwwroot\HISTORY\A02-OK.aspx    行: 39

    2007年6月11日 下午 03:24
  • 改寫後依然有問題..

    請大大幫忙看一下..

     

    <%@ Page Language="VB" Debug="true" ContentType="image/x-emf"%>
    <%@ Import Namespace="System.Drawing" %>
    <%@ Import Namespace="System.Drawing.Text" %>
    <%@ Import Namespace="System.Drawing.Imaging" %>
    <%@ Import Namespace="System.Drawing.Drawing2D" %>
    <%@ Import Namespace="System.Web.UI.Page" %>
    <%@ Import Namespace="NZlib.GZip" %>

    <script language=vb runat=server id="modResponseFile">
    Sub Page_Load(Sender As Object, E As EventArgs)
        ' ------------------------------------Metafile 宣告
        Dim bmp As New System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        Dim grfx As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
        Dim ipHdc As IntPtr = grfx.GetHdc()

        Dim stmMemory As New IO.MemoryStream
        Dim BitMap1 As New System.Drawing.Imaging.MetaFile(stmMemory,ipHdc)
        dim g = System.Drawing.Graphics.FromImage(BitMap1)
        '---------------------------------------------------
        'Dim stmMemory As New System.IO.MemoryStream
        'Dim BitMap1 As New Bitmap(800, 400,System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        'Dim g As System.Drawing.Graphics  = System.Drawing.Graphics.FromImage(BitMap1) 

        g.Clear(Color.FromArgb(0,255,255,255))
        Dim blueBrush As New SolidBrush(Color.Transparent)

        Dim F As New System.Drawing.Font("中國龍海報體", 140)
        Dim b As New System.Drawing.SolidBrush(Color.Red)
        g.DrawString("這是測試", F,new SolidBrush(Color.RED), 0, 0)


        'Response.ContentType = "image/emf"
        'BitMap1.Save(stmMemory, System.Drawing.Imaging.ImageFormat.emf)
        'stmMemory.WriteTo(Response.OutputStream)

        With Response
             .AddHeader("Content-disposition", "image/emf")
             .ContentType = "attachment; filename=test.emf"
             .BinaryWrite(stmMemory.toArray)
             .End()
        End With
    End SUB
    </script>

     

    描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。

    例外詳細資訊: System.ArgumentOutOfRangeException: 指定的引數超出有效值的範圍。
    參數名稱: offset

    原始程式錯誤:

    行 37:      .AddHeader("Content-disposition", "image/emf")
    行 38:      .ContentType = "attachment; filename=test.emf"
    行 39:      .BinaryWrite(stmMemory.toArray)
    行 40:      .End()
    行 41: End With

    原始程式檔: D:\InterNet Floder\wwwroot\HISTORY\A02-OK.aspx    行: 39

    2007年6月11日 下午 03:27
  • 經過幾次測試後..

    把IIS停了重新啟動又正常了..

    只是這次....

    沒有檔案產生...

    卻是再畫面上顯示一堆二進位亂碼........

    怎會這樣呢...

    大大救命啊..

    2007年6月11日 下午 04:04
  • 你的程式碼改成這樣:

    程式碼

     

    <%@ Page Language="VB" Debug="true" ContentType="image/x-emf"%>

    <%@ Import Namespace="System.Drawing" %>

    <%@ Import Namespace="System.Drawing.Text" %>

    <%@ Import Namespace="System.Drawing.Imaging" %>

    <%@ Import Namespace="System.Drawing.Drawing2D" %>

    <%@ Import Namespace="System.Web.UI.Page" %>

    <script language=vb runat=server id="modResponseFile">

         Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs)

              ' ------------------------------------Metafile 宣告

              Dim bmp As New System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

              Dim grfx As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)

              Dim ipHdc As IntPtr = grfx.GetHdc()

     

              Dim stmMemory As New IO.MemoryStream

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

             

              grfx.ReleaseHdc(ipHdc)

              grfx.Dispose()

              bmp.Dispose()

     

              grfx = System.Drawing.Graphics.FromImage(BitMap1)

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

     

              grfx.Clear(Color.FromArgb(0, 255, 255, 255))

              Dim blueBrush As New SolidBrush(Color.Transparent)

     

              Dim F As New System.Drawing.Font("標楷體", 140)

              Dim b As New System.Drawing.SolidBrush(Color.Red)

              grfx.DrawString("這是測試", F, New SolidBrush(Color.Red), 0, 0)

              grfx.Dispose()

     

              With Response

                   .AddHeader("Content-disposition", "image/emf")

                   .ContentType = "attachment; filename=test.emf"

                   .BinaryWrite(stmMemory.ToArray)

                   .End()

              End With

         End Sub

    </script>

     

    我改的用不同底色標記,其中淺綠色部分考量節省資源替換 g 為 grfx ,淺紫色的是重要結束繪圖,不可省略,省略的話 MemoryStream 會鎖住。

     

    即時繪製結果(長期將移除):

    2007年6月11日 下午 04:05
    版主
  • 亂碼問題解決了..

    是大大您的語法問題...

    不過解決就好了...

    但接下來...

    我想要知道EMZ該怎處理...

    可以請大大幫忙解惑嗎?

    謝謝~

    2007年6月11日 下午 04:27
  • EMZ 的作法在這邊貼過了,連程式碼都貼了,請先試做再討論:

    http://tlcheng.spaces.live.com/blog/cns!145419920BFD55A7!1543.entry

    2007年6月11日 下午 11:26
    版主