Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我的图元文件;“失去”;位图?_C#_Bitmap_Drawing_Metafile - Fatal编程技术网

C# 为什么我的图元文件;“失去”;位图?

C# 为什么我的图元文件;“失去”;位图?,c#,bitmap,drawing,metafile,C#,Bitmap,Drawing,Metafile,最近我在用图元文件绘制东西时发现了一个bug。现在我不确定我是否做错了什么,或者图元文件本身的图形中是否存在错误: 当在PlayenMetaFile在另一个图元文件本身上绘制的图元文件上绘制图像时,我会丢失远处或右侧的图像。我猜这与屏幕坐标有关(我运行的是双屏1280*1024,所以是2560*1024),因为图像开始消失的底线是500左右 下面是我创建的一些示例代码,以更具体地向您展示这个问题。(您只需使用此代码替换新创建的Windows C#项目的Form1.cs,并在其上放置一个按钮即可)

最近我在用图元文件绘制东西时发现了一个bug。现在我不确定我是否做错了什么,或者图元文件本身的图形中是否存在错误:

当在PlayenMetaFile在另一个图元文件本身上绘制的图元文件上绘制图像时,我会丢失远处或右侧的图像。我猜这与屏幕坐标有关(我运行的是双屏1280*1024,所以是2560*1024),因为图像开始消失的底线是500左右

下面是我创建的一些示例代码,以更具体地向您展示这个问题。(您只需使用此代码替换新创建的Windows C#项目的Form1.cs,并在其上放置一个按钮即可)

使用系统;
使用系统图;
使用System.Windows.Forms;
使用系统、绘图、成像;
使用System.IO;
使用System.Runtime.InteropServices;
命名空间元文件绘制
{ 
公共部分类表格1
:表格
{ 
[DllImport(“gdi32.dll”,SetLastError=true)]
私有静态外部布尔播放宏文件(IntPtr hdc、IntPtr hEmf、ref矩形);
[DllImport(“gdi32.dll”,SetLastError=true)]
公共静态外部布尔删除对象(IntPtr hGdiObj);
公共表格1()
{
初始化组件();
}
/// 
///创建完成实际图形(出现问题)的子图元文件。
/// 
私有图元文件GetSubMetafile()
{
图元文件图元文件=null;
使用(Graphics controlGraphics=this.CreateGraphics())
{
使用(MemoryStream MemoryStream=new MemoryStream())
{
图元文件=新图元文件(memoryStream,controlGraphics.GetHdc(),EmfType.EmfOnly,string.Empty);
使用(Graphics metafileGraphics=Graphics.FromImage(图元文件))
{
位图位图=新位图(“Fibonacci.png”);
//画3次图像…如果按到较低的位置,图像不会显示?
DrawRectangle(Pens.Yellow,新矩形(0,0,401200));
DrawImage(位图,新点(0,0));
DrawImage(位图,新点(10950));
DrawImage(位图,新点(201150));
}
}
controlGraphics.ReleaseHdc();
}
返回图元文件;
}
/// 
///创建并绘制图元文件。
/// 
私有void DrawMetafile()
{
使用(Graphics controlGraphics=this.CreateGraphics())
{    
使用(MemoryStream MemoryStream=new MemoryStream())
{
//EmfType.EmfOnly是由我的项目限制定义的限制
图元文件图元文件=新图元文件(memoryStream,controlGraphics.GetHdc(),EmfType.EmfOnly,string.Empty);
使用(Graphics metafileGraphics=Graphics.FromImage(图元文件))
{
//用于定向的大红色矩形
DrawRectangle(Pens.Red,新矩形(0,0,4000,4000));
//创建子图元文件
图元文件subMetafile=GetSubMetafile();
//要进行检查,请使用DrawImage绘制子数据文件(工作正常,内联图像绘制3次)
DrawImage(子文件,新点(10,0));
//在右侧,使用PlayenMetaFile绘制子图元文件(工作不正常,仅2个图像)
IntPtr hMetafile=subMetafile.GetHenhmetafile();
矩形矩形1=新矩形(100,0,170,1230);
PlayenMetaFile(metafileGraphics.GetHdc(),hMetafile,ref rectangle1);
metafileGraphics.ReleaseHdc();
DeleteObject(hMetafile);
}
保存(“Output.emf”);
}
controlGraphics.ReleaseHdc();
}
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
DrawMetafile();
}
}
}

如您所见,使用PlayenMetaFile函数会导致我丢失三个图像中的一个。有什么想法?

< p>我用C++来处理同样的问题,发现了两个解决办法。我可以使用GDI+附加到图元文件并播放它,但坐标有点偏离。我目前使用的更复杂的替代方法是使用EnumEnhMetaFile,并手动执行bitblt/stretchblt/stretchdibits调用,这似乎是可行的。如果您找到了更好的解决方案,请告诉我。

不幸的是,我使用Delphi遇到了同样的问题。这是一个真正的、语言不可知的GDI bug。
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();
  }
 }
}