作者: 乔克斯
查看: 6139|回复: 19

主题标签Tag

[源码] 【网页截图】网页全屏截图工具

[复制链接]
乔克斯 发表于 2014-10-10 14:33:50 | 显示全部楼层 |阅读模式
查看: 6139|回复: 19
网页全屏截图工具

效果图:
1.主界面。


2.CSkin论坛截图效果。



介绍说明:
一款实用简单的网页照相机,能够把整个网页从头到脚保存为一张图片。
原理比较简单,就是一个用一个虚拟的WebBrowser控件加载网页然后获取整个区域的图像并保存,核心类Screenshot.cs代码如下:
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Security;
namespace WebScreenshot
{
    public class Screenshot
    {
        public static Bitmap GetHtmlImage(Uri UrlString)
        {
            WebBrowser MyControl = new WebBrowser();
            MyControl.ScriptErrorsSuppressed = false;
            MyControl.Size = new Size(10, 10);
            MyControl.Url = UrlString;
            while (MyControl.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
            MyControl.Width = MyControl.Document.Body.ScrollRectangle.Width + 20;
            MyControl.Height = MyControl.Document.Body.ScrollRectangle.Height + 20;
            MyControl.Url = UrlString;
            WebControlImage.Snapshot snap = new WebControlImage.Snapshot();
            Bitmap MyImage = snap.TakeSnapshot(MyControl.ActiveXInstance, new Rectangle(0, 0, MyControl.Width, MyControl.Height));
            MyControl.Dispose();
            return MyImage;
        }
        /// 
        /// WebBrowser获取图形 
        /// 
        private class WebControlImage
        {
            internal static class NativeMethods
            {
                [StructLayout(LayoutKind.Sequential)]
                public sealed class tagDVTARGETDEVICE
                {
                    [MarshalAs(UnmanagedType.U4)]
                    public int tdSize;
                    [MarshalAs(UnmanagedType.U2)]
                    public short tdDriverNameOffset;
                    [MarshalAs(UnmanagedType.U2)]
                    public short tdDeviceNameOffset;
                    [MarshalAs(UnmanagedType.U2)]
                    public short tdPortNameOffset;
                    [MarshalAs(UnmanagedType.U2)]
                    public short tdExtDevmodeOffset;
                }
                [StructLayout(LayoutKind.Sequential)]
                public class COMRECT
                {
                    public int left;
                    public int top;
                    public int right;
                    public int bottom;
                    public COMRECT()
                    {
                    }
                    public COMRECT(Rectangle r)
                    {
                        this.left = r.X;
                        this.top = r.Y;
                        this.right = r.Right;
                        this.bottom = r.Bottom;
                    }
                    public COMRECT(int left, int top, int right, int bottom)
                    {
                        this.left = left;
                        this.top = top;
                        this.right = right;
                        this.bottom = bottom;
                    }
                    public static NativeMethods.COMRECT FromXYWH(int x, int y, int width, int height)
                    {
                        return new NativeMethods.COMRECT(x, y, x + width, y + height);
                    }
                    public override string ToString()
                    {
                        return string.Concat(new object[] { "Left = ", this.left, " Top ", this.top, " Right = ", this.right, " Bottom = ", this.bottom });
                    }
                }
                [StructLayout(LayoutKind.Sequential)]
                public sealed class tagLOGPALETTE
                {
                    [MarshalAs(UnmanagedType.U2)]
                    public short palVersion;
                    [MarshalAs(UnmanagedType.U2)]
                    public short palNumEntries;
                }
            }
            public class Snapshot
            {
              
                /// 图象大小 
                /// 
                public Bitmap TakeSnapshot(object pUnknown, Rectangle bmpRect)
                {
                    if (pUnknown == null)
                        return null;
                    //必须为com对象 
                    if (!Marshal.IsComObject(pUnknown))
                        return null;
                    //IViewObject 接口 
                    UnsafeNativeMethods.IViewObject ViewObject = null;
                    IntPtr pViewObject = IntPtr.Zero;
                    //内存图 
                    Bitmap pPicture = new Bitmap(bmpRect.Width, bmpRect.Height);
                    Graphics hDrawDC = Graphics.FromImage(pPicture);
                    //获取接口 
                    object hret = Marshal.QueryInterface(Marshal.GetIUnknownForObject(pUnknown),
                    ref UnsafeNativeMethods.IID_IViewObject, out pViewObject);
                    try
                    {
                        ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(UnsafeNativeMethods.IViewObject)) as UnsafeNativeMethods.IViewObject;
                        //调用Draw方法 
                        ViewObject.Draw((int)System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT,
                        -1,
                        IntPtr.Zero,
                        null,
                        IntPtr.Zero,
                        hDrawDC.GetHdc(),
                        new NativeMethods.COMRECT(bmpRect),
                        null,
                        IntPtr.Zero,
                        0);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        throw ex;
                    }
                    //释放 
                    hDrawDC.Dispose();
                    return pPicture;
                }
            }
            [SuppressUnmanagedCodeSecurity]
            internal static class UnsafeNativeMethods
            {
                public static Guid IID_IViewObject = new Guid("{0000010d-0000-0000-C000-000000000046}");
                [ComImport, Guid("0000010d-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
                public interface IViewObject
                {
                    [PreserveSig]
                    int Draw([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [In] NativeMethods.COMRECT lprcBounds, [In] NativeMethods.COMRECT lprcWBounds, IntPtr pfnContinue, [In] int dwContinue);
                    [PreserveSig]
                    int GetColorSet([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hicTargetDev, [Out] NativeMethods.tagLOGPALETTE ppColorSet);
                    [PreserveSig]
                    int Freeze([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [Out] IntPtr pdwFreeze);
                    [PreserveSig]
                    int Unfreeze([In, MarshalAs(UnmanagedType.U4)] int dwFreeze);
                    void SetAdvise([In, MarshalAs(UnmanagedType.U4)] int aspects, [In, MarshalAs(UnmanagedType.U4)] int advf, [In, MarshalAs(UnmanagedType.Interface)] System.Runtime.InteropServices.ComTypes.IAdviseSink pAdvSink);
                    void GetAdvise([In, Out, MarshalAs(UnmanagedType.LPArray)] int[] paspects, [In, Out, MarshalAs(UnmanagedType.LPArray)] int[] advf, [In, Out, MarshalAs(UnmanagedType.LPArray)] System.Runtime.InteropServices.ComTypes.IAdviseSink[] pAdvSink);
                }
            }
        }
    }
}



案例源码下载:

评分

参与人数 1金钱 +2 收起 理由
abweixx + 2

查看全部评分

回复 论坛版权

使用道具 举报

佐佑 发表于 2014-10-10 14:58:15 | 显示全部楼层
以前看到过一个JS版的。。。
easy 发表于 2014-10-11 16:52:47 | 显示全部楼层
回帖加积分,回帖加积分。。。。
流星 发表于 2015-1-21 11:32:02 | 显示全部楼层
看看。。。。。。
回复

使用道具 举报

hhjj3388 发表于 2015-1-25 13:10:32 | 显示全部楼层
不错 ···下来来学学·!!
snr19820216 发表于 2015-8-19 15:30:30 | 显示全部楼层
感谢分享,LZ辛苦了~
snr19820216 发表于 2015-8-19 15:30:45 | 显示全部楼层
感谢分享,LZ辛苦了~
X战警2015X 发表于 2015-8-23 03:21:04 | 显示全部楼层
666666有创意。虽然技术点不是很高。
1328842602 发表于 2015-10-17 18:36:51 | 显示全部楼层
小手一抖金币到手  楼主辛苦了
39095017 发表于 2015-11-1 14:25:27 | 显示全部楼层
非常给力,赞一个
您需要登录后才可以回帖 登录 | 加入CSkin博客

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2024-3-29 22:28, Processed in 0.696862 second(s), 40 queries , Gzip On.

快速回复 返回顶部 返回列表