C#将HTML代码转换为图片

前端通过富文本控件接收到了一段html代码,后端想通过图片的形式展示到另外的地方,这种情况怎么处理呢。直接上代码:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleApplication1
{
    /// <summary>
    /// 类说明:HTML代码转换为图片的公共类
    /// 作者:段江涛
    /// 时间:2019/10/17 11:16:38
    /// </summary>
    public class HtmlToPicHelper
    {
        private static Bitmap ConverHTML(string htmPath)
        {
            string ImagePath = string.Empty;
            WebBrowser web = new WebBrowser();
            web.Navigate(htmPath);
            while (web.ReadyState != WebBrowserReadyState.Complete)
            {
                System.Windows.Forms.Application.DoEvents();
            }
            Rectangle screen = Screen.PrimaryScreen.Bounds;
            Size? imgsize = null;
            //set the webbrowser width and hight
            web.Width = screen.Width;
            web.Height = screen.Height;
            //suppress script errors and hide scroll bars
            web.ScriptErrorsSuppressed = true;
            web.ScrollBarsEnabled = false;
            Rectangle body = web.Document.Body.ScrollRectangle;

            //check if the document width/height is greater than screen width/height
            Rectangle docRectangle = new Rectangle()
            {
                Location = new Point(0, 0),
                Size = new Size(body.Width > screen.Width ? body.Width : screen.Width,
                 body.Height > screen.Height ? body.Height : screen.Height)
            };
            //set the width and height of the WebBrowser object
            web.Width = docRectangle.Width;
            web.Height = docRectangle.Height;

            //if the imgsize is null, the size of the image will
            //be the same as the size of webbrowser object
            //otherwise  set the image size to imgsize
            Rectangle imgRectangle;
            if (imgsize == null)
                imgRectangle = docRectangle;
            else
                imgRectangle = new Rectangle()
                {
                    Location = new Point(0, 0),
                    Size = imgsize.Value
                };
            //create a bitmap object
            Bitmap bitmap = new Bitmap(imgRectangle.Width - 24, imgRectangle.Height);
            //get the viewobject of the WebBrowser
            IViewObject ivo = web.Document.DomDocument as IViewObject;

            using (Graphics g = Graphics.FromImage(bitmap))
            {
                //get the handle to the device context and draw
                IntPtr hdc = g.GetHdc();
                ivo.Draw(1, -1, IntPtr.Zero, IntPtr.Zero,
                         IntPtr.Zero, hdc, ref imgRectangle,
                         ref docRectangle, IntPtr.Zero, 0);
                g.ReleaseHdc(hdc);
            }
            return bitmap;
        }

        public static byte[] ConverPic(string htmlPath)
        {
            //必须放到独立的线程里面来处理
            Bitmap m_Bitmap = null;
            Thread m_thread = new Thread(new ThreadStart(() =>
            {
                m_Bitmap = ConverHTML(htmlPath);
            }));
            m_thread.SetApartmentState(ApartmentState.STA);
            m_thread.Start();
            m_thread.Join();

            if (m_Bitmap != null)
            {
                System.IO.MemoryStream ms=new System.IO.MemoryStream();
                m_Bitmap.Save(ms, ImageFormat.Jpeg);
                byte[] bs = ms.GetBuffer();
                ms.Close();
                return bs;
            }
            return new byte[0];
        }
    }


    [ComVisible(true), ComImport()]
    [GuidAttribute("0000010d-0000-0000-C000-000000000046")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IViewObject
    {
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int Draw(
            [MarshalAs(UnmanagedType.U4)] UInt32 dwDrawAspect,
            int lindex,
            IntPtr pvAspect,
            [In] IntPtr ptd,
            IntPtr hdcTargetDev,
            IntPtr hdcDraw,
            [MarshalAs(UnmanagedType.Struct)] ref Rectangle lprcBounds,
            [MarshalAs(UnmanagedType.Struct)] ref Rectangle lprcWBounds,
            IntPtr pfnContinue,
            [MarshalAs(UnmanagedType.U4)] UInt32 dwContinue);
        [PreserveSig]
        int GetColorSet([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect,
           int lindex, IntPtr pvAspect, [In] IntPtr ptd,
            IntPtr hicTargetDev, [Out] IntPtr 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)] IAdviseSink pAdvSink);
        void GetAdvise([In, Out, MarshalAs(UnmanagedType.LPArray)] int[] paspects,
          [In, Out, MarshalAs(UnmanagedType.LPArray)] int[] advf,
          [In, Out, MarshalAs(UnmanagedType.LPArray)] IAdviseSink[] pAdvSink);
    }

}

 这里面要注意几点:

1.首先需要引用程序集System.Drawing用于操作图片

2.需要引用程序集System.Windows.Forms,因为我们使用了控件 WebBrowser

3.大概使用思路就是将html保存到本地的一个文件中,然后把文件地址传递给ConverPic方法,完成之后再把创建的临时文件删除。

posted @ 2019-10-17 17:34  段江涛IT  阅读(5571)  评论(2编辑  收藏  举报
页脚HTML代码