Почему мой метафайл «теряет» растровое изображение? - PullRequest
0 голосов
/ 27 января 2011

Недавно я обнаружил ошибку при рисовании материала с метафайлами.Прямо сейчас я не уверен, что делаю что-то не так или есть ошибка в самом рисовании метафайлов:

При рисовании изображений в метафайле, который нарисован в другом метафайле PlayEnhMetafile, я теряю изображения далековниз или вправо.Я предполагаю, что это как-то связано с координатами экрана (я запускаю двойной экран 1280 * 1024, поэтому 2560 * 1024), потому что нижняя полоса, где изображения начинают исчезать, составляет около 500.

Вот примеркод, который я создал, чтобы показать вам проблему более конкретно.(Вы можете просто заменить Form1.cs только что созданного проекта Windows C # этим кодом и поместить на него кнопку)

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 приводит к потере одного изтри изображения.Есть идеи?

1 Ответ

0 голосов
/ 13 мая 2011

Я столкнулся с той же проблемой, используя C ++, и нашел два обходных пути. Я мог бы использовать GDI +, чтобы присоединиться к метафайлу и воспроизвести его, но координаты были немного смещены. Более сложная альтернатива, которую я сейчас использую, - это использование EnumEnhMetaFile, и, похоже, это работает, если вручную выполнять вызовы bitblt / stretchblt / stretchdibits. Если вы нашли лучшее решение, дайте мне знать.

...