如何通过 .Net 代码截取网站的屏幕截图?

发布于 2024-07-15 03:04:51 字数 59 浏览 4 评论 0原文

是否可以使用 .Net 代码截取任何给定 URL 的屏幕截图?

最简单的方法是什么?

Is it possible to take a screen shot of any given url using .Net code?

What is the easiest way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

走野 2024-07-22 03:04:51

只是偶然发现了这个:http://pietschsoft。 com/post/2008/07/C-Generate-WebPage-Thumbmail-Screenshot-Image.aspx

也许你可以使用一些东西?

放赐 2024-07-22 03:04:51

我建议使用第三方方法来执行此操作,而不是自己执行。 不过,如果您坚持这样做,那么最严厉的方法是使用 System.Diagnostics.Process 启动浏览器,然后使用 GetDesktopImage 获取屏幕截图。

我确信有一种更简单的方法,但看起来像这样:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

public class PlatformInvokeGDI32
{
    public  const int SRCCOPY = 13369376;

    [DllImport("gdi32.dll",EntryPoint="DeleteDC")]
    public static extern IntPtr DeleteDC(IntPtr hDc);

    [DllImport("gdi32.dll",EntryPoint="DeleteObject")]
    public static extern IntPtr DeleteObject(IntPtr hDc);

    [DllImport("gdi32.dll",EntryPoint="BitBlt")]
    public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp);

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,int nWidth, int nHeight);

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")]
    public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

    [DllImport ("gdi32.dll",EntryPoint="SelectObject")]
    public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp);
}

public class PlatformInvokeUSER32
{
    public const int SM_CXSCREEN = 0;
    public const int SM_CYSCREEN = 1;

    [DllImport("user32.dll", EntryPoint="GetDesktopWindow")]
    public static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll",EntryPoint="GetDC")]
    public static extern IntPtr GetDC(IntPtr ptr);

    [DllImport("user32.dll",EntryPoint="GetSystemMetrics")]
    public static extern int GetSystemMetrics(int abc);

    [DllImport("user32.dll",EntryPoint="GetWindowDC")]
    public static extern IntPtr GetWindowDC(Int32 ptr);

    [DllImport("user32.dll",EntryPoint="ReleaseDC")]
    public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc);
}

public class CaptureScreen
{
    public static Bitmap GetDesktopImage()
    {
        //In size variable we shall keep the size of the screen.
        SIZE size;

        //Variable to keep the handle to bitmap.
        IntPtr hBitmap;

        //Here we get the handle to the desktop device context.
        IntPtr  hDC = PlatformInvokeUSER32.GetDC(PlatformInvokeUSER32.GetDesktopWindow());

        //Here we make a compatible device context in memory for screen device context.
        IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);

        //We pass SM_CXSCREEN constant to GetSystemMetrics to get the
        //X coordinates of the screen.
        size.cx = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN);

        //We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of the screen.
        size.cy = PlatformInvokeUSER32.GetSystemMetrics (PlatformInvokeUSER32.SM_CYSCREEN);

        //We create a compatible bitmap of the screen size and using the screen device context.
        hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy);

        //As hBitmap is IntPtr, we cannot check it against null.
        //For this purpose, IntPtr.Zero is used.
        if(hBitmap != IntPtr.Zero)
        {
            //Here we select the compatible bitmap in the memeory device
            //context and keep the refrence to the old bitmap.
            IntPtr hOld = (IntPtr) PlatformInvokeGDI32.SelectObject(hMemDC, hBitmap);

            //We copy the Bitmap to the memory device context.
            PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY);

            //We select the old bitmap back to the memory device context.
            PlatformInvokeGDI32.SelectObject(hMemDC, hOld);

            //We delete the memory device context.
            PlatformInvokeGDI32.DeleteDC(hMemDC);

            //We release the screen device context.
            PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.GetDesktopWindow(), hDC);

            //Image is created by Image bitmap handle and stored in local variable.
            Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);

            //Release the memory to avoid memory leaks.
            PlatformInvokeGDI32.DeleteObject(hBitmap);

            //This statement runs the garbage collector manually.
            GC.Collect();

            //Return the bitmap
            return bmp;
        }

        //If hBitmap is null, retun null.
        return null;
    }
}

//This structure shall be used to keep the size of the screen.
public struct SIZE
{
  public int cx;
  public int cy;
}

I'd suggest using a third-party approach for this, not doing it yourself. If you insist, though, then the heavy-handed way is to use System.Diagnostics.Process to launch a browser, then GetDesktopImage to get a screenshot.

I'm sure there's an easier way, but that looks like this:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

public class PlatformInvokeGDI32
{
    public  const int SRCCOPY = 13369376;

    [DllImport("gdi32.dll",EntryPoint="DeleteDC")]
    public static extern IntPtr DeleteDC(IntPtr hDc);

    [DllImport("gdi32.dll",EntryPoint="DeleteObject")]
    public static extern IntPtr DeleteObject(IntPtr hDc);

    [DllImport("gdi32.dll",EntryPoint="BitBlt")]
    public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp);

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,int nWidth, int nHeight);

    [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")]
    public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

    [DllImport ("gdi32.dll",EntryPoint="SelectObject")]
    public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp);
}

public class PlatformInvokeUSER32
{
    public const int SM_CXSCREEN = 0;
    public const int SM_CYSCREEN = 1;

    [DllImport("user32.dll", EntryPoint="GetDesktopWindow")]
    public static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll",EntryPoint="GetDC")]
    public static extern IntPtr GetDC(IntPtr ptr);

    [DllImport("user32.dll",EntryPoint="GetSystemMetrics")]
    public static extern int GetSystemMetrics(int abc);

    [DllImport("user32.dll",EntryPoint="GetWindowDC")]
    public static extern IntPtr GetWindowDC(Int32 ptr);

    [DllImport("user32.dll",EntryPoint="ReleaseDC")]
    public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc);
}

public class CaptureScreen
{
    public static Bitmap GetDesktopImage()
    {
        //In size variable we shall keep the size of the screen.
        SIZE size;

        //Variable to keep the handle to bitmap.
        IntPtr hBitmap;

        //Here we get the handle to the desktop device context.
        IntPtr  hDC = PlatformInvokeUSER32.GetDC(PlatformInvokeUSER32.GetDesktopWindow());

        //Here we make a compatible device context in memory for screen device context.
        IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);

        //We pass SM_CXSCREEN constant to GetSystemMetrics to get the
        //X coordinates of the screen.
        size.cx = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN);

        //We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of the screen.
        size.cy = PlatformInvokeUSER32.GetSystemMetrics (PlatformInvokeUSER32.SM_CYSCREEN);

        //We create a compatible bitmap of the screen size and using the screen device context.
        hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy);

        //As hBitmap is IntPtr, we cannot check it against null.
        //For this purpose, IntPtr.Zero is used.
        if(hBitmap != IntPtr.Zero)
        {
            //Here we select the compatible bitmap in the memeory device
            //context and keep the refrence to the old bitmap.
            IntPtr hOld = (IntPtr) PlatformInvokeGDI32.SelectObject(hMemDC, hBitmap);

            //We copy the Bitmap to the memory device context.
            PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY);

            //We select the old bitmap back to the memory device context.
            PlatformInvokeGDI32.SelectObject(hMemDC, hOld);

            //We delete the memory device context.
            PlatformInvokeGDI32.DeleteDC(hMemDC);

            //We release the screen device context.
            PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.GetDesktopWindow(), hDC);

            //Image is created by Image bitmap handle and stored in local variable.
            Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap);

            //Release the memory to avoid memory leaks.
            PlatformInvokeGDI32.DeleteObject(hBitmap);

            //This statement runs the garbage collector manually.
            GC.Collect();

            //Return the bitmap
            return bmp;
        }

        //If hBitmap is null, retun null.
        return null;
    }
}

//This structure shall be used to keep the size of the screen.
public struct SIZE
{
  public int cx;
  public int cy;
}
那伤。 2024-07-22 03:04:51

有几个第三方组件可以执行此操作。 显然这并不是一件小事,因为 Flash 之类的东西并不那么容易捕捉。

我过去使用过 HTMLSnapshot 并且对它很满意(它不是免费的,但相当便宜)。

我衷心建议您不要浪费太多时间自己实现这一点,因为您最终肯定会重做这些第三方解决方案已经处理的许多最终案例。

There are several 3rd party components that does this. Apparently it's not trivial, since things like Flash and stuff don't capture so easily, for example.

I've used HTMLSnapshot in the past and was pleased with it (it's not free, but pretty cheap).

I heartily suggest you don't waste too much time implementing this yourself because you're bound to end up redoing a lot of end-cases that these 3rd party solutions already handle.

欢你一世 2024-07-22 03:04:51

我进行了广泛的搜索以找到此问题的解决方案,而使用 WebBrowser 和其他建议的问题是您需要对该框进行大量访问。

迄今为止,这是我能找到的最好的第三方工具:

http://www.websitesscreenshot.com/

他们的 SEO 很糟糕,但我相信我在论坛甚至 Stack 上找到了他们......我确实拥有一个许可证,你得到的只是一个可以引用的 DLL。 将许可证传递给建造者会删除他们的水印。

快速浏览一下 ILSpy 后,我相信它的作用是解释 HTML 并转储图像以供您观看。

使用

保存 URL

WebsitesScreenshot.WebsitesScreenshot  _Obj;
_Obj = new WebsitesScreenshot.WebsitesScreenshot ();
WebsitesScreenshot.WebsitesScreenshot.Result _Result;
_Result = _Obj.CaptureWebpage("http://www.google.com");
if (_Result == WebsitesScreenshot.WebsitesScreenshot.Result.Captured)
{
    _Obj.ImageFormat = WebsitesScreenshot.
        WebsitesScreenshot.ImageFormats.PNG;
    _Obj.SaveImage ("c:\\google.png");
}            
_Obj.Dispose();

保存原始 HTML 字符串

WebsitesScreenshot.WebsitesScreenshot _Obj;
_Obj=new WebsitesScreenshot.WebsitesScreenshot();
WebsitesScreenshot.WebsitesScreenshot.Result _Result;
_Result = _Obj.CaptureHTML(
"<html><body><h1> Hello world </h1></body></html>");
if (_Result == WebsitesScreenshot.WebsitesScreenshot.Result.Captured)
{
    _Obj.ImageFormat = WebsitesScreenshot.
        WebsitesScreenshot.ImageFormats.GIF;
    _Obj.SaveImage("c:\\test.gif");
}
_Obj.Dispose();

您可以在其使用页面上找到更多信息。 在这里找到:

http://www.websitesscreenshot.com/Usage.html

希望这有帮助!

干杯!!

I searched far and wide to find a solution to this problem and the issue with using the WebBrowser and other suggestions is that you need a lot of access to the box.

To date this is the best third party tool I have been able to find:

http://www.websitesscreenshot.com/

Their SEO is terrible, but I believe I found them on a forum or even Stack... I do own a license and what you get is just a single DLL you can reference. Passing a license to the constructor removes their watermark.

After a quick peek with ILSpy I believe what it does is that it interprets the HTML and dumps an image for your viewing pleasure.

Usage

Saving A URL

WebsitesScreenshot.WebsitesScreenshot  _Obj;
_Obj = new WebsitesScreenshot.WebsitesScreenshot ();
WebsitesScreenshot.WebsitesScreenshot.Result _Result;
_Result = _Obj.CaptureWebpage("http://www.google.com");
if (_Result == WebsitesScreenshot.WebsitesScreenshot.Result.Captured)
{
    _Obj.ImageFormat = WebsitesScreenshot.
        WebsitesScreenshot.ImageFormats.PNG;
    _Obj.SaveImage ("c:\\google.png");
}            
_Obj.Dispose();

Saving Raw HTML String

WebsitesScreenshot.WebsitesScreenshot _Obj;
_Obj=new WebsitesScreenshot.WebsitesScreenshot();
WebsitesScreenshot.WebsitesScreenshot.Result _Result;
_Result = _Obj.CaptureHTML(
"<html><body><h1> Hello world </h1></body></html>");
if (_Result == WebsitesScreenshot.WebsitesScreenshot.Result.Captured)
{
    _Obj.ImageFormat = WebsitesScreenshot.
        WebsitesScreenshot.ImageFormats.GIF;
    _Obj.SaveImage("c:\\test.gif");
}
_Obj.Dispose();

You can find more on their usage page. Found Here:

http://www.websitesscreenshot.com/Usage.html

Hope this helps !

Cheers!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文