WPFでスクリーン録画してみる
先日、WPFでスクリーンショットやスクリーン画面の動画を表示してみました。
elsammit-beginnerblg.hatenablog.com
今回はこちらのコードに録画機能を追加してスクリーン上の映像を録画してみようと思います!!
■OpenCVSharpを準備する
録画するにあたり、OpenCVSharpを用います。
OpenCVのC#版ですね。
OpenCVSharpですが、
Visual Studioを用いている場合には
Nugetパッケージ管理
を用いれば簡単にインストールが可能です。
Nugetパッケージ管理ですが、
ソリューションエクスプローラー上の参照を右クリックすると
こちらの通り、選択項目が出てくるのでこちらをクリック。
Nugetパッケージ管理が表示されたら、
上タブから「参照」を選択し、検索画面で「OpenCVSharp」と入力すると
こちらの通り複数バージョンのOpenCVSharpがリストで出力されます。
今回は、
・OpenCvSharp4
・OpenCvSharp4.runtime.win
をインストールしました。
合わせて、Extensionsも利用したいので、
・OpenCvSharp4.Extensions
もインストールします。
これでOpenCVSharpのインストールは完了です。
■WPFでスクリーン録画してみる
では本題のスクリーン録画を行ってみます。
xamlは前回と同様こちらのレイアウトとしました。
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Image x:Name="ImgCap" HorizontalAlignment="Left" Height="343" VerticalAlignment="Top" Width="525" Margin="62,34,0,0"/> <Button Content="start" HorizontalAlignment="Left" Height="54" Margin="656,351,0,0" VerticalAlignment="Top" Width="113" Click="Button_Click"/> </Grid> </Window>
録画開始するためのボタンと録画中の映像を表示するImagが1つずつあるのみの構成です。
次にC#のコードですが、こちらの通りになります。
using System; using System.Windows; using System.Windows.Media.Imaging; using System.Drawing; using System.Windows.Interop; using System.Threading; using OpenCvSharp; using OpenCvSharp.Extensions; namespace WpfApp1 { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : System.Windows.Window { public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { Thread thread = new Thread(new ThreadStart(() => { CaptureMovieAsync(); })); thread.Start(); } private void CaptureMovieAsync() { using (var writer = new VideoWriter("test.wmv", FourCC.WMV3, 5, new OpenCvSharp.Size((int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight))) { for (int i = 0; i < 100; i++) { using (var screenBmp = new System.Drawing.Bitmap( (int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { using (var bmpGraphics = Graphics.FromImage(screenBmp)) { bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size); Dispatcher.Invoke((Action)(() => { ImgCap.Source = Imaging.CreateBitmapSourceFromHBitmap( screenBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); Mat mat = BitmapConverter.ToMat(screenBmp).CvtColor(ColorConversionCodes.RGB2BGR); Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2RGB); Cv2.Resize(mat, mat, new OpenCvSharp.Size((int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight)); writer.Write(mat); })); } } Thread.Sleep(100); } } } } }
前回のスクリーンショット映像表示のみのコードから追加した点は2点です。
1点目は下記コードになります。
using (var writer = new VideoWriter("test.wmv", FourCC.WMV3, 5, new OpenCvSharp.Size((int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight)))
VideoWriterで動画ファイルへの書き込み用オブジェクトを生成します。
動画ファイルはwmvで出力したかったので、FourCCはWMV3としました。
また、動画サイズは画面サイズと合致するため、
new OpenCvSharp.Size((int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight)
としました。
2点目は下記のコードになります。
Mat mat = BitmapConverter.ToMat(screenBmp).CvtColor(ColorConversionCodes.RGB2BGR); Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2RGB); Cv2.Resize(mat, mat, new OpenCvSharp.Size((int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight)); writer.Write(mat);
こちらは、BitmapをMat型に型変換を行った後、
BGR⇒RGBに色変換とサイズ変更後、1点目で記載したVideoWriterへWriteしています。
本ループですが、、、
100ミリ秒のwaitで0から100までループさせているので、計10秒間実施しています。
要するに10秒間のスクリーン画面の録画を行っている、ということですね。
■最後に
今回はスクリーン画面を録画する方法をまとめてみました。
OpenCVが利用できるので、録画以外にもいろいろなことが出来そうですね。