2011-01-27 7 views
0

最近、私はメタファイルで物を描いている間にバグを発見しました。今私は何かが間違っているかどうか、またはメタファイルの図面内にバグがあるかどうかはわかりません:メタファイルがビットマップを「失う」のはなぜですか?

PlayEnhMetafileによって別のメタファイル自体に描画されたメタファイル上に画像を描画するとき、右の方へ。私は画面座標と関係があると思います(デュアルスクリーン1280 * 1024、2560 * 1024)ので、画像が消え始めるボトムレーンは約500です。

ここにいくつかの例があります問題をより具体的に示すために作成しました。あなたが見ることができるように、私は3の1を失うことになりPlayEnhMetaFile機能を使用して、

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(); 
    } 
} 
} 

を(あなたはこのコードを新規に作成したWindowsのC#プロジェクトのForm1.csをを交換し、その上にボタンを配置することができます)画像。何か案は?

答えて

0

C++を使用して同じ問題が発生し、2つの回避策が見つかりました。 GDI +を使ってメタファイルにアタッチして再生することはできましたが、座標は少しずれていました。私が現在使っているもっと複雑な代替方法は、EnumEnhMetaFileを使って、手動でbitblt/stretchblt/stretchdibits呼び出しを行うことです。これはうまくいくようです。より良い解決策が見つかったら私に教えてください。

関連する問題