3

私はこの行を持っています:

Process.Start("chrome.exe",
                "http://www.cnn.com");

新しいクロム ブラウザ ウィンドウを開いています。私は2つのことをしたい:

  1. クロムウィンドウを画像として変換/保存します。
  2. このウィンドウを非表示にします。

これは、新しいクラスで現在試しているコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Drawing;

namespace GatherLinks
{
    class WebSiteScreenShot
    {
        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
        [DllImport("user32.dll")]
        public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);

        public WebSiteScreenShot()
        {

        }

        public void WhateverMethod()
        {
            //initialize process and get hWnd
            Process putty = Process.Start("chrome.exe",
                "http://www.cnn.com");
            putty.WaitForInputIdle();
            IntPtr winHandle = putty.MainWindowHandle;

            //print screen
            RECT rc;
            GetWindowRect(winHandle, out rc);

            Bitmap bmp = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
            Graphics gfxBmp = Graphics.FromImage(bmp);
            IntPtr hdcBitmap = gfxBmp.GetHdc();

            PrintWindow(winHandle, hdcBitmap, 0);

            gfxBmp.ReleaseHdc(hdcBitmap);
            gfxBmp.Dispose();

            bmp.Save("c:\\temp\\test.png", ImageFormat.Png);

            //hides window
            ShowWindowAsync(winHandle, 0);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            private int _Left;
            private int _Top;
            private int _Right;
            private int _Bottom;

            public RECT(RECT Rectangle)
                : this(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom)
            {
            }
            public RECT(int Left, int Top, int Right, int Bottom)
            {
                _Left = Left;
                _Top = Top;
                _Right = Right;
                _Bottom = Bottom;
            }

            public int X
            {
                get { return _Left; }
                set { _Left = value; }
            }
            public int Y
            {
                get { return _Top; }
                set { _Top = value; }
            }
            public int Left
            {
                get { return _Left; }
                set { _Left = value; }
            }
            public int Top
            {
                get { return _Top; }
                set { _Top = value; }
            }
            public int Right
            {
                get { return _Right; }
                set { _Right = value; }
            }
            public int Bottom
            {
                get { return _Bottom; }
                set { _Bottom = value; }
            }
            public int Height
            {
                get { return _Bottom - _Top; }
                set { _Bottom = value + _Top; }
            }
            public int Width
            {
                get { return _Right - _Left; }
                set { _Right = value + _Left; }
            }
            public Point Location
            {
                get { return new Point(Left, Top); }
                set
                {
                    _Left = value.X;
                    _Top = value.Y;
                }
            }
            public Size Size
            {
                get { return new Size(Width, Height); }
                set
                {
                    _Right = value.Width + _Left;
                    _Bottom = value.Height + _Top;
                }
            }

            public static implicit operator Rectangle(RECT Rectangle)
            {
                return new Rectangle(Rectangle.Left, Rectangle.Top, Rectangle.Width, Rectangle.Height);
            }
            public static implicit operator RECT(Rectangle Rectangle)
            {
                return new RECT(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom);
            }
            public static bool operator ==(RECT Rectangle1, RECT Rectangle2)
            {
                return Rectangle1.Equals(Rectangle2);
            }
            public static bool operator !=(RECT Rectangle1, RECT Rectangle2)
            {
                return !Rectangle1.Equals(Rectangle2);
            }

            public override string ToString()
            {
                return "{Left: " + _Left + "; " + "Top: " + _Top + "; Right: " + _Right + "; Bottom: " + _Bottom + "}";
            }

            public override int GetHashCode()
            {
                return ToString().GetHashCode();
            }

            public bool Equals(RECT Rectangle)
            {
                return Rectangle.Left == _Left && Rectangle.Top == _Top && Rectangle.Right == _Right && Rectangle.Bottom == _Bottom;
            }

            public override bool Equals(object Object)
            {
                if (Object is RECT)
                {
                    return Equals((RECT)Object);
                }
                else if (Object is Rectangle)
                {
                    return Equals(new RECT((Rectangle)Object));
                }

                return false;
            }
        }

    }
}

まずクロムのウィンドウが開いていて、隠れていませんでした。次に、次の行で例外を開始します。

Bitmap bmp = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);

例外は次のとおりです。

ArguemntException パラメータが無効です

bmp が null で、Width と Height が 0 であることがわかります

このコードを Form1 で次のように使用しました。

WebSiteScreenShot wsss;

次に、コンストラクターで次のようにします。

wsss = new WebSiteScreenShot();
wsss.WhateverMethod();

ブレークポイントを使用して例外を取得しました。

これは例外の完全なメッセージです:

System.ArgumentException was unhandled
  HResult=-2147024809
  Message=Parameter is not valid.
  Source=System.Drawing
  StackTrace:
       at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
       at GatherLinks.WebSiteScreenShot.WhateverMethod() in d:\C-Sharp\GatherLinks\GatherLinks-2\GatherLinks\GatherLinks\WebSiteScreenShot.cs:line 38
       at GatherLinks.Form1..ctor() in d:\C-Sharp\GatherLinks\GatherLinks-2\GatherLinks\GatherLinks\Form1.cs:line 71
       at GatherLinks.Program.Main() in d:\C-Sharp\GatherLinks\GatherLinks-2\GatherLinks\GatherLinks\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
4

2 に答える 2

0

編集

Chrome の起動時に MainWindowHandle がないという問題を修正するプロセスの更新とスレッドの待機を追加しました。

注意事項:

Process.Refresh は、chrome の別のインスタンスが実行されていない場合にのみ機能します( chrome が既に実行されている場合、新しい Process により新しいタブが開かれ、終了するため、process.Refresh は失敗します) - これを回避するための他のアプローチが可能です。問題。

必要に応じてスレッドのスリープ値を微調整する必要があるかもしれませんが、ウィンドウ ハンドルが作成されてページが読み込まれるには、ある種の待機時間が必要です。

編集の終わり

これはそれを行う必要があります

  • プロセスを開始します(この場合はnotepad.exe)
  • ユーザー入力のために読み込まれるまで待機し、メイン ウィンドウ ハンドルを取得します。
  • 指定されたプロセスの印刷画面を取得します (これには、特定のアプリケーションのスクリーンショットを取得するで Maurice が提案したソリューションを使用しました。他のアプローチよりも複雑ですが、プロセスがフォアグラウンドにある必要はありません)
  • 画像を c:\temp\test.png に保存します
  • ShowWindowAsync を使用してプロセス ウィンドウを非表示にします

...
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Drawing.Imaging;
...
...
        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
        [DllImport("user32.dll")]
        public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);


        public WhateverMethod()
        {
             //initialize process and get hWnd
            Process chrome = Process.Start("chrome.exe","http://www.cnn.com");

            //wait for chrome window to open AND page to load (important for process refresh)
            //you might need to increase the sleep time for the page to load or monitor the "loading" title on Chrome

            System.Threading.Thread.Sleep(4000);
            chrome.Refresh();
            IntPtr mainHandle = chrome.MainWindowHandle;    

           RECT rc;
           GetWindowRect(mainHandle, out rc);

            Bitmap bmp = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
            Graphics gfxBmp = Graphics.FromImage(bmp);
            IntPtr hdcBitmap = gfxBmp.GetHdc();

            PrintWindow(mainHandle, hdcBitmap, 0);

            gfxBmp.ReleaseHdc(hdcBitmap);
            gfxBmp.Dispose();

            bmp.Save("c:\\temp\\test.png", ImageFormat.Png);
            ShowWindowAsync(mainHandle, 0);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            private int _Left;
            private int _Top;
            private int _Right;
            private int _Bottom;

            public RECT(RECT Rectangle)
                : this(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom)
            {
            }
            public RECT(int Left, int Top, int Right, int Bottom)
            {
                _Left = Left;
                _Top = Top;
                _Right = Right;
                _Bottom = Bottom;
            }

            public int X
            {
                get { return _Left; }
                set { _Left = value; }
            }
            public int Y
            {
                get { return _Top; }
                set { _Top = value; }
            }
            public int Left
            {
                get { return _Left; }
                set { _Left = value; }
            }
            public int Top
            {
                get { return _Top; }
                set { _Top = value; }
            }
            public int Right
            {
                get { return _Right; }
                set { _Right = value; }
            }
            public int Bottom
            {
                get { return _Bottom; }
                set { _Bottom = value; }
            }
            public int Height
            {
                get { return _Bottom - _Top; }
                set { _Bottom = value + _Top; }
            }
            public int Width
            {
                get { return _Right - _Left; }
                set { _Right = value + _Left; }
            }
            public Point Location
            {
                get { return new Point(Left, Top); }
                set
                {
                    _Left = value.X;
                    _Top = value.Y;
                }
            }
            public Size Size
            {
                get { return new Size(Width, Height); }
                set
                {
                    _Right = value.Width + _Left;
                    _Bottom = value.Height + _Top;
                }
            }

            public static implicit operator Rectangle(RECT Rectangle)
            {
                return new Rectangle(Rectangle.Left, Rectangle.Top, Rectangle.Width, Rectangle.Height);
            }
            public static implicit operator RECT(Rectangle Rectangle)
            {
                return new RECT(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom);
            }
            public static bool operator ==(RECT Rectangle1, RECT Rectangle2)
            {
                return Rectangle1.Equals(Rectangle2);
            }
            public static bool operator !=(RECT Rectangle1, RECT Rectangle2)
            {
                return !Rectangle1.Equals(Rectangle2);
            }

            public override string ToString()
            {
                return "{Left: " + _Left + "; " + "Top: " + _Top + "; Right: " + _Right + "; Bottom: " + _Bottom + "}";
            }

            public override int GetHashCode()
            {
                return ToString().GetHashCode();
            }

            public bool Equals(RECT Rectangle)
            {
                return Rectangle.Left == _Left && Rectangle.Top == _Top && Rectangle.Right == _Right && Rectangle.Bottom == _Bottom;
            }

            public override bool Equals(object Object)
            {
                if (Object is RECT)
                {
                    return Equals((RECT)Object);
                }
                else if (Object is Rectangle)
                {
                    return Equals(new RECT((Rectangle)Object));
                }

                return false;
            }
        }

于 2013-07-01T03:24:10.250 に答える
-1

答えが遅いと思いますが、この問題を抱えている人はwkhtmltopdf と wkhtmltoimage を試してください。これらは、Qt WebKit レンダリング エンジンを使用して HTML を PDF およびさまざまな画像形式にレンダリングするオープン ソース (LGPLv3) コマンド ライン ツールです。これらは完全に「ヘッドレス」で実行され、表示または表示サービスを必要としません。

基本的に、Web ページ全体を PDF または画像形式に変換できます。

于 2016-05-09T07:52:57.067 に答える