C#如何在应用程序中截取.NET控件屏幕并将其附加到Outlook邮件

8
有人知道如何使用C#截取屏幕并限制它只截取应用程序中特定容器/部分的图像吗?我不想要整个屏幕或应用程序的整个窗口。我的面板只是称为:panel1,用户将单击一个“按钮”并截取panel1的屏幕截图并附加到电子邮件中。我想仅截取该部分的屏幕截图,然后在本地保存到C:\驱动器中和/或附加或嵌入到Outlook电子邮件中。我在互联网上读到了其他各种东西,但大多数都涉及创建复杂的更改以截取Web浏览器控件的屏幕截图,而我不需要这样做。

很奇怪,所有这些答案都涵盖了问题的重复部分,而没有一个涉及标题中原始部分。 - Alejandro
6个回答

8
如果您只想要Panel的屏幕截图,您可以使用内置的DrawToBitmap方法。
Bitmap bmp = new Bitmap(myPanel.Width, myPanel.Height);
myPanel.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save(@"C:\MyPanelImage.bmp");

请注意,某些控件可能无法与此功能配合使用,例如WebBrowserRichTextBox控件,但它应该适用于大多数其他控件(如文本框、标签等)。


谢谢,这两行代码是我所缺失的关键。Bitmap bmp = new Bitmap(myPanel.Width, myPanel.Height); myPanel.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height)); - brink668
这回答了如何制作屏幕截图的第一部分问题。然后是Outlook和其他东西。但无论如何,我都在这里解决第一部分问题。 - Bitterblue

5
我会使用类似以下代码来实现这个任务:

我使用类似以下代码:

public static void TakeCroppedScreenShot(
    string fileName, int x, int y, int width, int height, ImageFormat format)
{
    Rectangle r = new Rectangle(x, y, width, height);
    Bitmap bmp = new Bitmap(r.Width, r.Height, PixelFormat.Format32bppArgb);
    Graphics g = Graphics.FromImage(bmp);
    g.CopyFromScreen(r.Left, r.Top, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
    bmp.Save(fileName, format);
}

I hope this helps


1
实际上,已经有一个与此相关的问题:https://dev59.com/oXA75IYBdhLWcg3wboUz - MoonKnight

3
一份对Asif答案的改进:
注:此处为HTML标签,不进行翻译。
public static Bitmap takeComponentScreenShot(Control control)
{
    // find absolute position of the control in the screen.
    Rectangle rect=control.RectangleToScreen(control.Bounds);

    Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
    Graphics g = Graphics.FromImage(bmp);

    g.CopyFromScreen(rect.Left, rect.Top, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);

    return bmp;
}

这怎么算是一种改进呢? - beresfordt
计算矩形的另一种逻辑有时会失败。 - Pedro Duarte
1
为什么另一个失败了而这个工作了?像这样的事情在回答中包含是有用的! - beresfordt

2

Killercam的回答进行轻微修改:

    public static Bitmap takeComponentScreenShot(Control control)
    {
        // find absolute position of the control in the screen.
        Control ctrl  = control;
        Rectangle rect = new Rectangle(Point.Empty, ctrl.Size);
        do
        {
            rect.Offset(ctrl.Location);
            ctrl = ctrl.Parent;
        }
        while (ctrl != null);

        Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
        Graphics g = Graphics.FromImage(bmp);

        g.CopyFromScreen(rect.Left, rect.Top, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);

        return bmp;
    }

该方法将立即拍摄屏幕截图。例如,如果在调用此函数之前在面板内更改按钮的可见性,则位图将包含该按钮。如果不需要这样,请使用keyboardP的答案

1
我发现可以将控件保存为位图,代码如下:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void Button1_Click(object sender, EventArgs e)
    {
        SaveAsBitmap(panel1,"C:\\path\\to\\your\\outputfile.bmp");
    }

    public void SaveAsBitmap(Control control, string fileName)
    {   
        //get the instance of the graphics from the control
        Graphics g = control.CreateGraphics();

        //new bitmap object to save the image
        Bitmap bmp = new Bitmap(control.Width, control.Height);

        //Drawing control to the bitmap
        control.DrawToBitmap(bmp, new Rectangle(0, 0, control.Width, control.Height));

        bmp.Save(fileName);
        bmp.Dispose();

    }
}

我在这里找到了有关Outlook的信息, 但是我无法测试它,因为我的电脑上没有安装Outlook。


1

修改了KeyboardP的答案。修改为静态方法,以便用作助手。

public static Bitmap ScreenShotaControl(Control aControl)
        {
            try
            {
                Bitmap bmp = new Bitmap(aControl.Width, aControl.Height);
                aControl.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
                return bmp;
            }
            catch (Exception)
            {

                throw;
            }
        }

例子用法如下:

Bitmap bmp = ScreenShotaControl(aControl);
    Clipboard.SetImage(bmp); //to copy to clipboard

Bitmap bmp = ScreenShotaControl(aControl);
    bmp.Save(@"C:\MyPanelImage.bmp"); //save to specified path

Bitmap bmp = ScreenShotaControl(aControl);
    MemoryStream ms= new MemoryStream();
    bmp.Save(ms, ImageFormat.Jpeg); 
    ContentType ct= new ContentType(); 
    ct.MediaType = MediaTypeNames.Image.Jpeg; 

    MailMessage mail = new MailMessage(); 
    mail.Attachments.Add(new Attachment(ms, ct));  //attach to email

2
我认为这可以回答“如何使该方法静态?”但它对原始问题没有添加任何重要内容。 - Alejandro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接