2011-01-27 66 views
0

最近我發現了一個bug,同時用元文件繪製東西。現在我不確定我是否做錯了什麼或者圖元文件本身有錯誤:爲什麼我的圖元文件會「丟失」一個位圖?

在通過PlayEnhMetafile在另一個元文件本身上繪製的元文件上繪製圖像時,我失去了遠處的圖像或在右邊。我猜它與屏幕座標有關(我運行雙屏幕1280 * 1024,所以2560 * 1024),導致圖像開始消失的底部通道大約爲500.

這是一些示例代碼我創建了更具體地向您顯示問題。 (你可以只使用此代碼替換新創建的Windows C#項目的Form1.cs和其上放置一個按鈕)

using System; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Drawing.Imaging; 
using System.IO; 
using System.Runtime.InteropServices; 

namespace MetaFileDrawing 
{ 
public partial class Form1 
    : Form 
{ 
    [DllImport("gdi32.dll", SetLastError = true)] 
    private static extern bool PlayEnhMetaFile(IntPtr hdc, IntPtr hEmf, ref Rectangle rectangle); 

    [DllImport("gdi32.dll", SetLastError = true)] 
    public static extern bool DeleteObject(IntPtr hGdiObj); 

    public Form1() 
    { 
    InitializeComponent(); 
    } 

    /// <summary> 
    /// Creates the sub-metafile where the actual drawing is done (and the problems occur). 
    /// </summary> 
    private Metafile GetSubMetafile() 
    { 
    Metafile metafile = null; 
    using(Graphics controlGraphics = this.CreateGraphics()) 
    { 
    using(MemoryStream memoryStream = new MemoryStream()) 
    { 
    metafile = new Metafile(memoryStream, controlGraphics.GetHdc(), EmfType.EmfOnly, string.Empty); 

    using(Graphics metafileGraphics = Graphics.FromImage(metafile)) 
    { 
     Bitmap bitmap = new Bitmap("Fibonacci.png"); 
     // Draw the image 3 times... if pushed to far down, it wont show up? 
     metafileGraphics.DrawRectangle(Pens.Yellow, new Rectangle(0, 0, 40, 1200)); 
     metafileGraphics.DrawImage(bitmap, new Point(0, 0)); 
     metafileGraphics.DrawImage(bitmap, new Point(10, 950)); 
     metafileGraphics.DrawImage(bitmap, new Point(20, 1150)); 
    } 
    } 
    controlGraphics.ReleaseHdc(); 
    } 
    return metafile; 
    } 

    /// <summary> 
    /// Creates and draws the metafile. 
    /// </summary> 
    private void DrawMetafile() 
    { 
    using(Graphics controlGraphics = this.CreateGraphics()) 
    {  
    using(MemoryStream memoryStream = new MemoryStream()) 
    { 
    // EmfType.EmfOnly is a restriction defined by my project limitations 
    Metafile metafile = new Metafile(memoryStream, controlGraphics.GetHdc(), EmfType.EmfOnly, string.Empty); 

    using(Graphics metafileGraphics = Graphics.FromImage(metafile)) 
    { 
     // A large red rect for orientation 
     metafileGraphics.DrawRectangle(Pens.Red, new Rectangle(0, 0, 4000, 4000)); 

     // Create the sub metafile 
     Metafile subMetafile = GetSubMetafile(); 

     // To check, draw the subMetafile with DrawImage (works fine, the inlined image is drawn 3 times) 
     metafileGraphics.DrawImage(subMetafile, new Point(10, 0)); 

     // On the right side, draw the sub metafile using PlayEnhMetaFile (dont work correctly, only 2 images) 
     IntPtr hMetafile = subMetafile.GetHenhmetafile(); 
     Rectangle rectangle1 = new Rectangle(100, 0, 170, 1230); 
     PlayEnhMetaFile(metafileGraphics.GetHdc(), hMetafile, ref rectangle1); 
     metafileGraphics.ReleaseHdc(); 
     DeleteObject(hMetafile); 
    } 

    metafile.Save("Output.emf"); 
    } 
    controlGraphics.ReleaseHdc(); 
    } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
    DrawMetafile(); 
    } 
} 
} 

正如你所看到的,使用PlayEnhMetaFile功能使我失去了三選一圖片。有任何想法嗎?

回答

0

我遇到了使用C++的相同問題,並找到了兩種解決方法。我可以使用GDI +附加到圖元文件並播放,但座標稍微偏離。我目前使用的更復雜的替代方法是使用EnumEnhMetaFile,並手動執行bitblt/stretchblt/stretchdibits調用,這似乎工作。如果您找到了更好的解決方案,請告訴我。

相關問題