WPFに便利な形式で画面にスクリーンショットを取得する

しばらく前に、モニター画面全体またはその特定の領域からプログラムでスナップショットを作成できるツールが必要でした。 この場合、領域をプログラムで指定するだけでなく、ユーザーがマウスで手動で指定する必要があります。 結果は、受け取った画面をGUI(グラフィカルユーザーインターフェイス)に表示するのに便利なクラスの1つのインスタンスにすぐにパックする必要があります。





最終結果をどのクラスにパックするかについての私の決定は、WPFでの(クラス)の使用の利便性によるものです。

System.Drawing.BitmapクラスにはSaveメソッドが含まれています。これにより、受信した画像をラスターイメージファイルに書き込むことができます(作成するファイルの種類を示します)。

System.Windows.Media.Imaging.BitmapImageクラスは、ビットマップイメージを表示するためにWPFで使用されるSystem.Windows.Controls.Imageのデータソースとしてよく使用されます。

画像をデータベーステーブルに保存できるようにするためにSystem.IO.MemoryStreamクラスが必要でしたが、もちろん、これはこの形式で表示される画像が必要な唯一のケースではありません。



既製のソリューションをGoogleで検索し、自分の欲求を完全に満たすものを見つけられなかった後、座ってライブラリを書きました。 必要な機能を静的クラスのメソッドの形式で実装することにしました。 クラスにScreenManagerという名前を付けます。 次のメソッドを実装する必要があります。







最終結果は、それに関する情報を含むxmlファイルを含むdllライブラリの形式で提示する必要があります。



実行するアクションのロジックに従って異なるcsファイル間でコードを配布するために、ScreenManagerクラスを部分的にしています。 このようなファイルが3つあります。



ProgramMethods.csファイルには、ユーザーが手動で領域の境界を指定することなく、画面全体またはその領域を透過モードで撮影できるメソッドが含まれています。

一方、ManualMethods.csファイルは、写真を撮影する画面の領域の表示をユーザーに要求するメソッドをカプセル化する必要があります。 ユーザーはマウスの左ボタンをクリックする必要があります。これにより、領域の最初のコーナーを示し、ボタンを離さずに、反対の対角を指定し、押したボタンを離します。 画面上でマウスポインターを移動するプロセスでは、選択した境界線の領域を何らかの色の長方形で示し、モニター画面上のマウスの移動中に動的にサイズを変更する必要があります。 エリアの選択中にユーザーがエスケープキーを押した場合、キャプチャコマンドを中止する必要があります。 ScreenManagerクラスのRectangleBrushおよびRectangleLineWeigthの静的プロパティを使用して、四角形の色と線の太さをカスタマイズできる必要があります。

InnerMethods.csファイルには、ManualMethods.csファイルのコードが機能するために必要な補助メソッドのセットが含まれます。



ライブラリコードを完全に作成したら、テストアプリケーションを作成して(「WPFテスト」と呼びます)、ライブラリのデモを行う必要があります。 これは、必要なデモンストレーションに十分なImageおよびButtonオブジェクトを備えた小さなWPFウィンドウになります。



さて、それですべてです...以下は、上記で私が言及したcs-ファイルのソースコードです:

ProgramMethods.csファイル



1: using System;<br> 2: using System.Collections. Generic ;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows.Forms;<br> 6: using System.Drawing;<br> 7: using System.Drawing.Imaging;<br> 8: using System.Windows.Media.Imaging;<br> 9: using System.IO;<br> 10: using System.Windows.Shapes;<br> 11: using System.Windows.Controls;<br> 12: using System.Windows.Input;<br> 13: using System.Windows;<br> 14: <br> 15: namespace Bushman.Screens<br> 16: {<br> 17: /// <summary> <br> 18: /// <br> 19: /// <br> 20: /// </summary> <br> 21: public static partial class ScreenManager<br> 22: {<br> 23: // , (.. ). <br> 24: /// <summary> <br> 25: /// , BitmapImage. . <br> 26: /// </summary> <br> 27: /// <param name="rect"> System.Drawing.Rectangle, , <br> 28: /// </param> <br> 29: /// <param name="format"> , </param> <br> 30: /// <returns> , BitmapImage</returns> <br> 31: public static BitmapImage GetBitmapImageFromScreen(System.Drawing.Rectangle rect, ImageFormat format)<br> 32: {<br> 33: using (MemoryStream ms = new MemoryStream())<br> 34: {<br> 35: Screen screen = Screen.FromRectangle(rect);<br> 36: Bitmap bitmap = new Bitmap (rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); <br> 37: Graphics graphics = Graphics .FromImage(bitmap);<br> 38: graphics.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy); <br> 39: bitmap.Save(ms, format);<br> 40: BitmapImage img = new BitmapImage();<br> 41: img.BeginInit();<br> 42: img.CacheOption = BitmapCacheOption.OnLoad;<br> 43: img.StreamSource = ms;<br> 44: img.EndInit();<br> 45: return img;<br> 46: }<br> 47: }<br> 48: /// <summary> <br> 49: /// , BitmapImage. . <br> 50: /// </summary> <br> 51: /// <returns> , BitmapImage</returns> <br> 52: public static BitmapImage GetBitmapImageFromScreen( ImageFormat format)<br> 53: {<br> 54: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);<br> 55: return GetBitmapImageFromScreen(rect, format);<br> 56: }<br> 57: <br> 58: /// <summary> <br> 59: /// , MemoryStream. . <br> 60: /// </summary> <br> 61: /// <param name="rect"> System.Drawing.Rectangle, , <br> 62: /// </param> <br> 63: /// <param name="format"> , </param> <br> 64: /// <returns> , MemoryStream</returns> <br> 65: public static MemoryStream GetMemoryStreamFromScreen(System.Drawing.Rectangle rect, ImageFormat format)<br> 66: {<br> 67: MemoryStream ms = new MemoryStream();<br> 68: Screen screen = Screen.FromRectangle(rect);<br> 69: Bitmap bitmap = new Bitmap (rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);<br> 70: Graphics graphics = Graphics .FromImage(bitmap);<br> 71: graphics.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy);<br> 72: bitmap.Save(ms, format);<br> 73: return ms;<br> 74: }<br> 75: <br> 76: /// <summary> <br> 77: /// , MemoryStream. . <br> 78: /// </summary> <br> 79: /// <returns> , MemoryStream</returns> <br> 80: public static MemoryStream GetMemoryStreamFromScreen( ImageFormat format)<br> 81: {<br> 82: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);<br> 83: return GetMemoryStreamFromScreen(rect, format);<br> 84: }<br> 85: <br> 86: /// <summary> <br> 87: /// , Bitmap. . <br> 88: /// </summary> <br> 89: /// <param name="rect"> System.Drawing.Rectangle, , <br> 90: /// </param> <br> 91: /// <returns> , Bitmap</returns> <br> 92: public static Bitmap GetBitmapFromScreen(System.Drawing.Rectangle rect)<br> 93: {<br> 94: Screen screen = Screen.FromRectangle(rect);<br> 95: Bitmap bitmap = new Bitmap (rect.Width, rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);<br> 96: Graphics graphics = Graphics .FromImage(bitmap);<br> 97: graphics.CopyFromScreen(rect.X, rect.Y, 0, 0, rect.Size, CopyPixelOperation.SourceCopy); <br> 98: return bitmap;<br> 99: }<br> 100: <br> 101: /// <summary> <br> 102: /// , Bitmap. . <br> 103: /// </summary> <br> 104: /// <returns> , Bitmap</returns> <br> 105: public static Bitmap GetBitmapFromScreen()<br> 106: {<br> 107: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);<br> 108: return GetBitmapFromScreen(rect);<br> 109: }<br> 110: }<br> 111: } <br><br> * This source code was highlighted with Source Code Highlighter .







ファイルManualMethods.cs



1: using System;<br> 2: using System.Collections. Generic ;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows.Forms;<br> 6: using System.Drawing;<br> 7: using System.Drawing.Imaging;<br> 8: using System.Windows.Media.Imaging;<br> 9: using System.IO;<br> 10: using System.Windows.Shapes;<br> 11: using System.Windows.Controls;<br> 12: using System.Windows.Input;<br> 13: using System.Windows;<br> 14: <br> 15: namespace Bushman.Screens<br> 16: {<br> 17: // , () <br> 18: public static partial class ScreenManager<br> 19: {<br> 20: // , () , <br> 21: //************************************** <br> 22: <br> 23: // , : <br> 24: static Window win; //, <br> 25: static System.Windows.Point firstPoint; // <br> 26: static System.Windows.Point secondPoint; // ( ) <br> 27: static Canvas canvas;<br> 28: static System.Windows.Controls.Image image;<br> 29: static List <Line> lines; // , <br> 30: static ImageFormat format;<br> 31: static MemoryStream result;<br> 32: static System.Windows.Media.Brush rectangleBrush = System.Windows.Media.Brushes.Black;<br> 33: static double rectangleLineWeigth = 5;<br> 34: <br> 35: /// <summary> <br> 36: /// , <br> 37: /// </summary> <br> 38: public static System.Windows.Media.Brush RectangleBrush<br> 39: {<br> 40: get { return rectangleBrush; }<br> 41: set { rectangleBrush = value ; }<br> 42: }<br> 43: /// <summary> <br> 44: /// , <br> 45: /// </summary> <br> 46: public static double RectangleLineWeigth<br> 47: {<br> 48: get { return rectangleLineWeigth; }<br> 49: set { rectangleLineWeigth = value ; }<br> 50: }<br> 51: <br> 52: /// <summary> <br> 53: /// , <br> 54: /// </summary> <br> 55: /// <param name="imgFormat"> , </param> <br> 56: /// <returns> MemoryStream</returns> <br> 57: public static MemoryStream GetMemoryStreamFromScreenManually( ImageFormat imgFormat)<br> 58: {<br> 59: format = imgFormat;<br> 60: // , <br> 61: win = new Window() { WindowState = WindowState.Maximized, WindowStyle = WindowStyle.None };<br> 62: <br> 63: // , BitmapImage <br> 64: BitmapImage bitmapImage = ScreenManager.GetBitmapImageFromScreen( ImageFormat .Png);<br> 65: <br> 66: // <br> 67: image = new System.Windows.Controls.Image() { Source = bitmapImage };<br> 68: canvas = new Canvas() { Width = Screen.PrimaryScreen.Bounds.Width, Height = Screen.PrimaryScreen.Bounds.Height };<br> 69: canvas.Children.Add(image);<br> 70: Canvas.SetTop(image, 0);<br> 71: Canvas.SetLeft(image, 0);<br> 72: win.Content = canvas;<br> 73: <br> 74: // <br> 75: image.MouseLeftButtonDown += new MouseButtonEventHandler(image_MouseLeftButtonDown);<br> 76: // <br> 77: // <br> 78: image.MouseMove += new System.Windows.Input.MouseEventHandler(image_MouseMove);<br> 79: <br> 80: //================ <br> 81: //************************************************************ <br> 82: //================ <br> 83: <br> 84: // , 2- , <br> 85: // , <br> 86: image.MouseLeftButtonUp += new MouseButtonEventHandler(image_MouseLeftButtonUp);<br> 87: // Escape , , <br> 88: image.KeyDown += new System.Windows.Input.KeyEventHandler(image_KeyDown);<br> 89: // <br> 90: win.ShowDialog();<br> 91: return result;<br> 92: }<br> 93: <br> 94: /// <summary> <br> 95: /// , <br> 96: /// </summary> <br> 97: /// <param name="imgFormat"> , </param> <br> 98: /// <returns> Bitmap</returns> <br> 99: public static Bitmap GetBitmapFromScreenManually( ImageFormat imgFormat)<br> 100: {<br> 101: MemoryStream ms = GetMemoryStreamFromScreenManually(imgFormat);<br> 102: return new Bitmap (ms);<br> 103: }<br> 104: <br> 105: /// <summary> <br> 106: /// , <br> 107: /// </summary> <br> 108: /// <param name="imgFormat"> , </param> <br> 109: /// <returns> BitmapImage</returns> <br> 110: public static BitmapImage GetBitmapImageFromScreenManually( ImageFormat imgFormat)<br> 111: {<br> 112: MemoryStream ms = GetMemoryStreamFromScreenManually(imgFormat);<br> 113: BitmapImage bitmapImg = new BitmapImage();<br> 114: bitmapImg.BeginInit();<br> 115: bitmapImg.CacheOption = BitmapCacheOption.OnLoad;<br> 116: bitmapImg.StreamSource = ms;<br> 117: bitmapImg.EndInit();<br> 118: bitmapImg.Freeze();<br> 119: return bitmapImg;<br> 120: }<br> 121: }<br> 122: } <br><br> * This source code was highlighted with Source Code Highlighter .







InnerMethods.csファイル



1: using System;<br> 2: using System.Collections. Generic ;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows.Forms;<br> 6: using System.Drawing;<br> 7: using System.Drawing.Imaging;<br> 8: using System.Windows.Media.Imaging;<br> 9: using System.IO;<br> 10: using System.Windows.Shapes;<br> 11: using System.Windows.Controls;<br> 12: using System.Windows.Input;<br> 13: using System.Windows;<br> 14: <br> 15: namespace Bushman.Screens<br> 16: {<br> 17: // , () <br> 18: public static partial class ScreenManager<br> 19: {<br> 20: static void image_KeyDown( object sender, System.Windows.Input.KeyEventArgs e)<br> 21: {<br> 22: if (e.Key == Key.Escape) win.Close();<br> 23: }<br> 24: <br> 25: static void image_MouseLeftButtonDown( object sender, MouseButtonEventArgs e)<br> 26: {<br> 27: firstPoint = e.GetPosition(win);<br> 28: lines = new List <Line>();<br> 29: for ( int i = 0; i < 4; i++)<br> 30: {<br> 31: Line item = new Line();<br> 32: item.Stroke = RectangleBrush;<br> 33: item.StrokeThickness = RectangleLineWeigth;<br> 34: canvas.Children.Add(item);<br> 35: Canvas.SetTop(item, firstPoint.Y);<br> 36: Canvas.SetLeft(item, firstPoint.X);<br> 37: item.StrokeEndLineCap = System.Windows.Media.PenLineCap.Round;<br> 38: item.StrokeStartLineCap = System.Windows.Media.PenLineCap.Round;<br> 39: item.Y2 = 0;<br> 40: item.X2 = 0;<br> 41: lines.Add(item);<br> 42: item.MouseLeftButtonUp += new MouseButtonEventHandler(image_MouseLeftButtonUp);<br> 43: item.KeyDown += new System.Windows.Input.KeyEventHandler(image_KeyDown);<br> 44: }<br> 45: }<br> 46: <br> 47: static void image_MouseMove( object sender, System.Windows.Input.MouseEventArgs e)<br> 48: {<br> 49: if (e.LeftButton == MouseButtonState.Pressed)<br> 50: {<br> 51: lines[0].Y2 = e.GetPosition(win).Y - firstPoint.Y;<br> 52: <br> 53: lines[1].X2 = e.GetPosition(win).X - firstPoint.X;<br> 54: <br> 55: lines[2].Y1 = lines[0].Y2;<br> 56: lines[2].Y2 = lines[2].Y1;<br> 57: lines[2].X2 = lines[1].X2;<br> 58: <br> 59: lines[3].X1 = lines[1].X2;<br> 60: lines[3].X2 = lines[3].X1;<br> 61: lines[3].Y2 = lines[0].Y2;<br> 62: }<br> 63: }<br> 64: <br> 65: static void image_MouseLeftButtonUp( object sender, MouseButtonEventArgs e)<br> 66: {<br> 67: GetSecondPoint(e.GetPosition(win));<br> 68: }<br> 69: <br> 70: static void GetSecondPoint(System.Windows.Point point)<br> 71: {<br> 72: foreach (Line line in lines)<br> 73: {<br> 74: canvas.Children.Remove(line);<br> 75: }<br> 76: secondPoint = point;<br> 77: int top = ( int ) Math .Min(firstPoint.Y, secondPoint.Y);<br> 78: int left = ( int ) Math .Min(firstPoint.X, secondPoint.X);<br> 79: int height = ( int )( Math .Max(firstPoint.Y, secondPoint.Y) - Math .Min(firstPoint.Y, secondPoint.Y));<br> 80: int width = ( int )( Math .Max(firstPoint.X, secondPoint.X) - Math .Min(firstPoint.X, secondPoint.X));<br> 81: <br> 82: // , , <br> 83: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(left, top, width, height);<br> 84: result = ScreenManager.GetMemoryStreamFromScreen(rect, format);<br> 85: // <br> 86: win.Close();<br> 87: }<br> 88: //************************************** <br> 89: }<br> 90: } <br><br> * This source code was highlighted with Source Code Highlighter .







以下は、WpfTestテストアプリケーションコードです。



Window1.xamlファイル



1: < Window x:Class ="WpfTest.Window1" <br> 2: xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <br> 3: xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" <br> 4: Title ="ScreenManager testing" Height ="300" Width ="300" > <br> 5: < Grid > <br> 6: < Grid.RowDefinitions > <br> 7: < RowDefinition Height ="100*" /> <br> 8: < RowDefinition Height ="Auto" /> <br> 9: </ Grid.RowDefinitions > <br> 10: < Image Name ="img" HorizontalAlignment ="Center" ></ Image > <br> 11: < StackPanel Name ="stack" Grid . Row ="1" > <br> 12: < Button Name ="btnSaveScreen" > Save screen (manually method) </ Button > <br> 13: </ StackPanel > <br> 14: </ Grid > <br> 15: </ Window > <br><br> * This source code was highlighted with Source Code Highlighter .







ファイルWindow1.xaml.cs



1: using System;<br> 2: using System.Collections. Generic ;<br> 3: using System.Linq;<br> 4: using System.Text;<br> 5: using System.Windows;<br> 6: using System.Windows.Controls;<br> 7: using System.Windows.Data;<br> 8: using System.Windows.Documents;<br> 9: using System.Windows.Input;<br> 10: using System.Windows.Media;<br> 11: using System.Windows.Media.Imaging;<br> 12: using System.Windows.Navigation;<br> 13: using System.Windows.Shapes;<br> 14: using System.Drawing.Imaging;<br> 15: using System.Drawing;<br> 16: using Bushman.Screens;<br> 17: using System.IO;<br> 18: <br> 19: namespace WpfTest<br> 20: {<br> 21: /// <summary> <br> 22: /// Interaction logic for Window1.xaml <br> 23: /// </summary> <br> 24: public partial class Window1 : Window<br> 25: {<br> 26: public Window1()<br> 27: {<br> 28: InitializeComponent();<br> 29: MyInitialize();<br> 30: }<br> 31: void MyInitialize()<br> 32: {<br> 33: btnSaveScreen.Click += new RoutedEventHandler(btnSaveScreenManually_Click);<br> 34: }<br> 35: <br> 36: void btnSaveScreenManually_Click( object sender, RoutedEventArgs e)<br> 37: {<br> 38: string dirName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "ScreenResults" );<br> 39: DirectoryInfo dir = new DirectoryInfo(dirName);<br> 40: if (!dir.Exists) dir = Directory .CreateDirectory(dirName);<br> 41: System.Drawing.Rectangle rect = new System.Drawing.Rectangle(50, 50, 300, 200);<br> 42: Bitmap bitmap;<br> 43: MemoryStream ms;<br> 44: <br> 45: /// , . , <br> 46: /// . <br> 47: <br> 48: // 1 <br> 49: //bitmap = ScreenManager.GetBitmapFromScreen(); <br> 50: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetBitmapFromScreen_0.png")); <br> 51: //bitmap.Dispose(); <br> 52: <br> 53: // 2 <br> 54: //bitmap = ScreenManager.GetBitmapFromScreen(rect); <br> 55: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetBitmapFromScreen_1.png")); <br> 56: //bitmap.Dispose(); <br> 57: <br> 58: // 3 <br> 59: //bitmap = ScreenManager.GetBitmapFromScreenManually(ImageFormat.Png); <br> 60: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetBitmapFromScreenManually.png")); <br> 61: //bitmap.Dispose(); <br> 62: <br> 63: // 4 <br> 64: //img.Source = ScreenManager.GetBitmapImageFromScreen(ImageFormat.Png); <br> 65: <br> 66: // 5 <br> 67: //img.Source = ScreenManager.GetBitmapImageFromScreen(rect, ImageFormat.Png); <br> 68: <br> 69: // 6 <br> 70: img.Source = ScreenManager.GetBitmapImageFromScreenManually( ImageFormat .Png);<br> 71: <br> 72: // 7 <br> 73: //ms = ScreenManager.GetMemoryStreamFromScreen(ImageFormat.Png); <br> 74: //bitmap = new Bitmap(ms); <br> 75: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetMemoryStreamFromScreen_0.png")); <br> 76: //bitmap.Dispose(); <br> 77: <br> 78: // 8 <br> 79: //ms = ScreenManager.GetMemoryStreamFromScreen(rect, ImageFormat.Png); <br> 80: //bitmap = new Bitmap(ms); <br> 81: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetMemoryStreamFromScreen_1.png")); <br> 82: //bitmap.Dispose(); <br> 83: <br> 84: // 9 <br> 85: //ms = ScreenManager.GetMemoryStreamFromScreenManually(ImageFormat.Png); <br> 86: //bitmap = new Bitmap(ms); <br> 87: //bitmap.Save(System.IO.Path.Combine(dir.FullName, "GetMemoryStreamFromScreenManually.png")); <br> 88: //bitmap.Dispose(); <br> 89: }<br> 90: }<br> 91: } <br><br> * This source code was highlighted with Source Code Highlighter .







テストアプリケーションの結果は次のようになります(結果は「ScreenManagerテスト」ウィンドウに表示されます)。







コードは、MS Visual Studio 2008 SP1および.Net Framework 3.5 SP1を使用して記述されています。

プロジェクトのソースコードはこちらです。

ライブラリのリリースバージョンはこちらです。



All Articles