【问题标题】:How can I get a screenshot of control? DrawToBitmap not working如何获得控制截图? DrawToBitmap 不工作
【发布时间】:2012-05-24 16:17:24
【问题描述】:

我有一个通过 dll 调用在外部绘制的图片框。

private void myPictureBox_Paint(object sender, PaintEventArgs e)
{
     dllClass.RefreshEx(LWHANDLE, 0, 0);
}

这一切正常,但我现在需要获取该图片框的屏幕截图,但它无法正常工作。

这是我尝试过的:

        Control ctrlToDraw = myPictureBox;

        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ctrlToDraw.Width, ctrlToDraw.Height);
        ctrlToDraw.DrawToBitmap(bmp, ctrlToDraw.ClientRectangle); 

我也尝试过通过 Windows API 来实现,但它得到的结果与上面的代码完全相同:一个空白(非空)图像。

除了截取整个屏幕的屏幕截图之外,有人能提出一些建议吗?

【问题讨论】:

  • 您确定您的外部调用实际上正在绘制到图片框,因为我只是按原样测试了您的代码,并且它运行良好。是绘制到图片框,还是在图片框图形对象上绘制?因为这里可能存在持久性问题
  • @K'Leg 它确实可以与普通图片​​框完美配合 :( 它只是不适用于这个。这是一个巨大的该死项目,我不能轻易发布 SSCCE。
  • 我只需要知道你的外部是如何与这个程序对话的,以及绘图例程的代码是什么

标签: c# .net winforms drawtobitmap


【解决方案1】:

我不知道您对外部程序有多少控制权,也不知道它如何绘制到您的图片框,但如果您使用 createGraphics,它将无法工作。

private void button1_Click(object sender, EventArgs e)
    {
        //here I am calling the graphics object of the Picture Box, this will draw to the picture box
        //But the DrawToBitmap, will not reflect this change, and once the Picturebox needs to be updated, this will disappear.
        Graphics g = pictureBox1.CreateGraphics();
        g.DrawRectangle(Pens.Blue, 10, 10, 20, 20);

        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(pictureBox1.Width, pictureBox1.Height);
        Rectangle bounds = new Rectangle(Left, Top, Width, Height);
        pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
        //Draws whatever is in the PictureBox to the Forms BackgroundImage
        this.BackgroundImage = bmp;
        //It will not draw the Blue rectangle

    }

如果您的外部程序要绘制位图,那么您可以将该位图设置为图片框背景

    Bitmap buffer;
    public Form1()
    {
        InitializeComponent();
        buffer = new Bitmap(pictureBox1.Width, pictureBox1.Height);
    }


    private void button1_Click(object sender, EventArgs e)
    {
        //draw to the bitmap named buffer
        using (Graphics g = Graphics.FromImage(buffer))
        {
            g.DrawRectangle(Pens.Blue, 10, 10, 20, 20);
        }
        //assign the picturebox image to buffer
        pictureBox1.Image = buffer;

        //Now this will show the blue rectangle
        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(pictureBox1.Width, pictureBox1.Height);
        Rectangle bounds = new Rectangle(Left, Top, Width, Height);
        pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);

        this.BackgroundImage = bmp;
    }

编辑魅力第三次

这将截取屏幕截图,剪掉图片框,然后我更改了表单背景,只是为了证明它有效。

你需要添加

using System.Drawing.Imaging;

适用于像素格式。

 private void button1_Click(object sender, EventArgs e)
    {
        using (Graphics G = pictureBox1.CreateGraphics())
        {
            G.DrawRectangle(Pens.Blue, 10, 10, 10, 10);
        }
        Bitmap BMP = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                        Screen.PrimaryScreen.Bounds.Height,
                                        PixelFormat.Format32bppArgb);
        using (Graphics GFX = Graphics.FromImage(BMP))
        {
            GFX.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                                Screen.PrimaryScreen.Bounds.Y,
                                0, 0,
                                Screen.PrimaryScreen.Bounds.Size,
                                CopyPixelOperation.SourceCopy);
        }
        Bitmap YourPictureBoxImage = new Bitmap(pictureBox1.Width,pictureBox1.Height);
        using (Graphics g = Graphics.FromImage(YourPictureBoxImage))
        {
            Point np = pictureBox1.PointToScreen(new Point(0, 0));
            g.DrawImage(BMP,new Rectangle(0,0,100,100),new Rectangle(np,pictureBox1.Size),GraphicsUnit.Pixel);
        }

        this.BackgroundImage = YourPictureBoxImage;
    }

【讨论】:

  • 外部程序所拥有的只是图片框的“句柄”。这就是传递给它的所有内容。所以我猜它直接绘制它,而不是设置图像或其他方式。不过我会试试你的代码。
  • “直接向它绘画”,可能是通过使用 bitBlt 和 srcCopy。我现在无权访问源代码。
  • 这太糟糕了,因为在我看来,它是在借鉴它,而不是它。你能看到画框,当它在上面画画的时候?一旦图片框中有图像,尝试最小化表单,然后将其恢复,图像是否还在?
  • 图像甚至从未出现在那里(因为它被外部程序中的其他图像绘制为 ON)。我只能假设它一次又一次地重新粉刷非常快。
  • 首先添加一些东西到你的图片框,看看它是否会改变,我认为你的问题的开始就在那里。我为您编写了一个新示例,它完全符合您的要求。它需要一个屏幕截图,切出你的图片框供你使用,但如果你在你的框中看不到任何东西,那么屏幕截图也没有任何东西可以捕捉
【解决方案2】:

您可以使用 ALT+PRINTSCREEN 仅截取活动窗口的屏幕截图。这会将当前活动窗口作为位图捕获到剪贴板。将其粘贴到位图编辑工具中,裁剪到您想要的区域。

或者使用允许在屏幕上裁剪目标区域的屏幕捕获实用程序,例如 Evernote 版本 2 的旧屏幕剪辑器。

【讨论】:

  • 请问我怎样才能通过代码做到这一点?我忘了说背景可以动态变化。
  • 您的问题是“不是完整的屏幕截图”。您没有要求在代码中根据需要自动捕获屏幕的一部分。当您提出问题时,这些细节很重要。我知道自动屏幕捕获实用程序,但我必须考虑这个新要求。
猜你喜欢
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 1970-01-01
  • 2019-01-28
相关资源
最近更新 更多