午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

WPFのBitmapSource用のデバッガービジュアライザー作ってみた

WPFのBitmapSource用のデバッガービジュアライザー作ってみた

f:id:gogowaten:20200113214247p:plain

ダウンロード先

MyVisualizer.zip

展開してMyVisualizer.dllを

ドキュメントフォルダにある使いたいバージョンのVisual StudioのVisualizersフォルダに入れるだけ

ユーザー名がwatenでVisual Studioのバージョンが2019なら

C:\Users\ユーザー名\Documents\Visual Studio 2019\Visualizers

対象のフレームワーク.NET Framework 4.7.2だからこれより古いのだと動かないかも?

2020/03/18追記

.NET Coreで使うなら

C:\Users\ユーザー名\Documents\Visual Studio 2019\Visualizers\netcoreapp

netcoreappフォルダは初期状態だと存在しないから新規作成

追記ここまで

 

作って動かしている環境は

OS:Windows 10 Home 64bit

VS:Visual Studio Community 2019

 

github.com

 

 

これを使うとデバッグ中のBitmapSource型の変数の中にある画像を表示することができる、たとえば

f:id:gogowaten:20200113103352p:plain

52行目で画像ファイルを読み込んで

53行目で切り抜き

54行目でPixelFormatを変換

この途中経過の

63行目で一時停止するようにしておいてデバッグ実行して

 

f:id:gogowaten:20200113103843p:plain

それぞれの変数にカーソルを合わせると出てくる虫眼鏡アイコンをクリックすると

 

f:id:gogowaten:20200113104008p:plain

ダイアログで画像が表示される、画像処理のアプリを作るときにあると便利

虫眼鏡アイコンはピン留めや画面下にあるローカルウィンドウのでも同じみたい

 

 

作り方手順メモ

 

  1. 新しいプロジェクトの作成
  2. プロジェクトにデバッガービジュアライザーを追加する
  3. 参照の追加
  4. デバッガービジュアライザーにコードを書いていく
  5. 確認テスト
  6. releaseでビルドしたものをVisual Studioに追加

 

1.新しいプロジェクトの作成

f:id:gogowaten:20200113105005p:plain

クラスライブラリ(.NET Framework)を選択、これ重要、似たものに

クラスライブラリ(.NET Standard)ってのがあるけど、これではできなかった

 

f:id:gogowaten:20200113105653p:plain

クラスライブラリ(.NET Framework)を選択(大事なことなので)

Sutandardはなんか違ったんだよねえ(1敗)

 

 

適当なプロジェクト名をつける

f:id:gogowaten:20200113110939p:plain

MyVisualizer

にした、これがdllの名前になる

 

作成ボタンを押して

f:id:gogowaten:20200113111258p:plain

ソリューションエクスプローラーを表示して、参照の項目を展開したところ
表示されているコードはClass1.csっていう自動で作成されたファイルのものなんだけど、これ使わないんだよねえ、よくわからん

 

 

2.プロジェクトにデバッガービジュアライザーを追加する

方法
メニューのプロジェクト→新しい項目の追加、
もしくは
ソリューションエクスプローラーでプロジェクト名の右クリックメニューから追加→新しい項目

f:id:gogowaten:20200113112850p:plain


開かれたダイアログの

f:id:gogowaten:20200113113232p:plain

一覧からデバッガービジュアライザーを選択して適当な名前をつける
MyDialog

にした、追加ボタンを押すと

 

f:id:gogowaten:20200113113411p:plain

デバッガービジュアライザーを追加したところ

なんかいっぱい書いてある

このときのソリューションエクスプローラーを見ると

 

f:id:gogowaten:20200113113944p:plain

デバッガービジュアライザー(MyDialog.cs)がプロジェクトに追加されているのがわかる、

その他にも必要な参照3つ

Microsoft.VisualStudio.DebuggerVisualizers

System.Drawing

System.Windows.Forms

が追加されている、かしこい

WPFのBitmapSourceを表示するには少し足りないので

 

 

3.参照の追加

方法は
メニューのプロジェクト→参照の追加、

もしくは
ソリューションエクスプローラーでプロジェクト名の右クリックメニューから追加→参照

f:id:gogowaten:20200113114740p:plain

これで参照マネージャーが表示される

f:id:gogowaten:20200113114954p:plain

右下の参照ボタンから追加できる
追加する参照は2つあってPresentationCore、WindowsBaseの2つ、これのパスは

  • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationCore.dll
  • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\WindowsBase.dll

なんだけどv4.7.2とかのバージョンらしきものはプロジェクトのものと合わせたほうがいいのかも?

たとえばPresentationCoreでデスクトップ検索すると

f:id:gogowaten:20200113120110p:plain

いっぱい出てくる

 

確認はプロジェクトのプロパティのアプリケーションの項目の対象のフレームワークで確認できる

f:id:gogowaten:20200113115846p:plain

メニューのプロジェクト→(プロジェクト名)のプロパティで

 

f:id:gogowaten:20200113115952p:plain

対象のフレームワークってとこ、今回はこの数値と同じ場所にあるdllを追加した

 

追加後のソリューションエクスプローラーの様子

f:id:gogowaten:20200113120631p:plain

それぞれ追加したdllの役目は
PresentationCoreはBitmapSourceなどWPF側で使う
WindowsBaseもInt32RectなどWPF

 


4.デバッガービジュアライザーにコードを書いていく


usingの追加は
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

f:id:gogowaten:20200113121126p:plain

 

 

BitmapSourceをシリアライズできる型に分解するクラスを作成

/// <summary>
/// BitmapSourceをシリアライズできる型に分解
/// PixelFormatをBgra32に決め打ち方式用
/// </summary>
[Serializable]
public class MyProxy
{
    public int Width { get; private set; }
    public int Height { get; private set; }
    public int Stride { get; private set; }
    public byte[] Pixels { get; private set; }

    public MyProxy(BitmapSource source)
    {
        if (source.Format != PixelFormats.Bgra32)
        {
            source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
        }
        Width = source.PixelWidth;
        Height = source.PixelHeight;
        Stride = Width * 4;// (Width * source.Format.BitsPerPixel + 7) / 8;
        Pixels = new byte[Height * Stride];
        source.CopyPixels(new Int32Rect(0, 0, Width, Height), Pixels, Stride, 0);
    }
}

BitmapSource作成に最低限必要な要素を持つシリアライズ可能なクラス

名前はMyProxyにした、Proxyは代理、仲介とか

これを書いた場所は

f:id:gogowaten:20200113123629p:plain

ここ、MyDialogクラスの外なのでソリューションエクスプローラーでみると

MyDialog.cs

┣MyDialog

┗MyProxy

 

BitmapSourceは

  • 幅Width、
  • 高さHeight、
  • Stride1行のByte数、
  • PixelsPixelの色データ、
  • PixelFormatピクセルフォーマット

この5つがあれば作成できる、それぞれの型はint, int, int, byte, PixelFormat、この中でPixelFormatだけはシリアライズできない型。

デバッガービジュアライザーで表示可能なのはできるのはシリアライズできる型だけらしくて、BitmapSourceはできない型!

なのでなんとかシリアライズできる型に分解したけどPixelFormatだけはムリ、ではないけどめんどくさかったり難しいので、どんなピクセルフォーマットの画像でもBgra32に変換して統一することにして、このクラスが持つのはシリアライズできるint型とbyte型の2種類。

クラスの頭に[Serializable]をつけているのは、このクラスはシリアライズできますっていう宣言?みたいなもの

 

BitmapSource→デバッガービジュアライザー→エラー

こうだったのを

BitmapSource→MyProxy→デバッガービジュアライザー→表示

こんな感じにするため?

 

 

VisualizerObjectSourceを継承したクラス作成

f:id:gogowaten:20200113130831p:plain

public class MySource : VisualizerObjectSource

クラスの名前はMySourceにした、書いた場所はMyProxyと同じようにMyDialogクラスの外側、結果ソリューションエクスプローラーでみると

MyDialog.cs

┣MyDialog

┣MySource

┗MyProxy

になった

 

f:id:gogowaten:20200113131424p:plain

GetDataメソッドをオーバーライド

 

f:id:gogowaten:20200113131517p:plain

targetにBitmapSourceが入ってきて、それをStream型にして返すメソッド?

このままだとBitmapSourceが送り出されて結果エラーになるので、さっき書いたMyProxyクラスに変換して送り出す

 

f:id:gogowaten:20200113132120p:plain

受け取ったBitmapSourceからMyProxyを作成して、それを送り出す感じ?

 


Showメソッドの書き換え

f:id:gogowaten:20200113132702p:plain

よくわからん日本語が書いてあるけど、受け取った物を表示するところみたい
40行目、object data = (object)objectProvider.GetObject();

ここのdataに受け取ったものが入って

44行目以降でdataをFormで表示する

 

このGetObject()メソッドが、さっき書いたGetDataメソッドに繋がっているらしくてMyProxyが返ってくるので

MyProxy→BitmapSource→Bitmap

に変換する

BitmapSourceはFormに表示できないのでBitmapに変換する必要がある

 

MyProxy→BitmapSource

f:id:gogowaten:20200113140250p:plain

BitmapSourceのCreateメソッドを使ってMyProxyからBitmapSourceを作成

 

f:id:gogowaten:20200113140425p:plain

PixelFormatはBgra32に統一することにしたので決め打ち

 

BitmapSource→Bitmap

f:id:gogowaten:20200113140750p:plain

BitmapのLockBitsとBitmapSourceのCopyPixelsで、BitmapSourceのデータをBitmapに流し込んでいる感じ、これでBitmap完成

BitmapのPixelFormatはFormat32bppArgbってのにしているけど、これは

BitmapSourceのPixelFormat.Bgra32と互換性があるみたいで、これで問題なくできた

 

 

表示部分

f:id:gogowaten:20200113141845p:plain

BitmapはPictureBoxに表示して、それをFormに追加することにしたので

 

f:id:gogowaten:20200113142429p:plain

こう書き換えた、Dispose()はこれであっているかなあ

 

f:id:gogowaten:20200113142850p:plain

書き換え後のShowメソッド


TestShowVisualizerメソッドの書き換え

f:id:gogowaten:20200113143133p:plain

このままだとテストで動かない?ので書き換え

 

f:id:gogowaten:20200113144150p:plain

書き換え後、引数を一つ足しただけで

 

f:id:gogowaten:20200113144158p:plain

3つ目の引数にMySourceクラスを指定



属性?アセンブリ情報?を追加

f:id:gogowaten:20200113144850p:plain

namespaceの上に付け加える、よくわからん

f:id:gogowaten:20200113145457p:plain

最初の引数にはビジュアライザーの型を指定するとあるこれは

f:id:gogowaten:20200113145725p:plain

このDialogDebuggerVisualizerを継承したクラスで

 

2つ目の引数

f:id:gogowaten:20200113145507p:plain

ビジュアライザーオブジェクトソースの型とあるので

f:id:gogowaten:20200113145902p:plain

このVisualizerObjectSourceを継承したクラスをそれぞれ指定するみたい

3つ目の引数は表示したいものだからBitmapSourceで

4つ目は虫眼鏡アイコンのリストに表示したい文字列を指定、

今回は🐭びっとまっぷそぉす🐭にした

これでデバッガービジュアライザーができたはずなので

ビルド

f:id:gogowaten:20200113150401p:plain

これで

f:id:gogowaten:20200113150503p:plain

dllが作成される

今回は

C:\Users\waten\Source\Repos\wpf_test2\MyVisualizer\MyVisualizer\bin\Debug

に作成された、次は期待通りに動くのかテスト

 

 

5.確認テスト

確認テスト用のプロジェクトをソリューションに追加

f:id:gogowaten:20200113150807p:plain

テストするには別のプロジェクトが必要らしので、ソリューションエクスプローラーのソリューションの右クリックメニューから追加→新しいプロジェクトから

 

f:id:gogowaten:20200113151005p:plain

コンソールアプリ(.NET Framework)を選択して次へ

 

f:id:gogowaten:20200113151232p:plain

名前はそのままConsoleApp1にした

作成ボタン押して

 

f:id:gogowaten:20200113151335p:plain

ソリューションにConsoleApp1が追加された

ソリューションエクスプローラーでも確認、参照の項目も展開したところ

 

プロジェクトをスタートアッププロジェクトに設定

f:id:gogowaten:20200113153308p:plain

ソリューションエクスプローラーでプロジェクト(新しく追加したほう)の右クリックメニューからスタートアッププロジェクトに設定をクリック

 

参照の追加

追加するのは3つ

  • PresentationCore
  • Microsoft.VisualStudio.DebuggerVisualizers
  • さっきビルドしたdll

PresentationCoreはデバッガービジュアライザーに追加したものと同じ、次のDebuggerVisualizersはデバッガービジュアライザーのものと同じものでいいのかなと思ったのでオブジェクトブラウザーで確認してみる

f:id:gogowaten:20200113154413p:plain

ソリューションエクスプローラーのデバッガービジュアライザーの参照にあるDebuggerVisualizersの右クリックメニューからオブジェクトブラウザーで表示をクリック

 

f:id:gogowaten:20200113154532p:plain

右下にパスが表示されている、これを追加することにした

それぞれのパスは

  • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\PresentationCore.dll
  • C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.DebuggerVisualizers.dll
  • C:\Users\waten\Source\Repos\wpf_test2\MyVisualizer\MyVisualizer\bin\Debug\MyVisualizer.dll

 

f:id:gogowaten:20200113155017p:plain

3つをテスト用のプロジェクトの参照に追加したところ

テストのコード

f:id:gogowaten:20200113155457p:plain

BitmapSourceをつかうので

using System.Windows.Media.Imaging;

を追加しておいて

f:id:gogowaten:20200113155755p:plain

14行目は画像ファイルからBitmapIamgeを作成、BitmapIamgeはBitmapSourceに派生みたいなものなので、これを15行目でデバッガービジュアライザーのTestShowVisualizerメソッドにBitmapImageを渡している

これでテスト準備完了!

デバッグの開始すると

f:id:gogowaten:20200113162533p:plain

真っ黒のウィンドウが表示された直後、その上に

 

f:id:gogowaten:20200113162603p:plain

画像が表示されたウィンドウが表示される、このウィンドウがデバッガービジュアライザーで表示されたもの、このウィンドウを閉じると真っ黒のウィンドウも閉じられてデバッグ終了になる

 

f:id:gogowaten:20200113163017p:plain

16行目で一時停止するようにして実行、15行目でさっきと同じようにウィンドウが表示されるのでそれを閉じて16行目まですすめて

f:id:gogowaten:20200113163540p:plain

imageの上にカーソルを持っていくと虫眼鏡アイコン

 

f:id:gogowaten:20200113163547p:plain

虫眼鏡アイコンの右の▼をクリックで登録しておいた文字列🐭びっとまっぷそぉす🐭が表示されてる!クリックで

 

f:id:gogowaten:20200113163555p:plain

Formが表示された!

 

もし期待通りに動かなかったら

  1. デバッガービジュアライザーのコードを修正
  2. ビルドしてから
  3. デバッグ開始(F5)

これを繰り返すんだけど、よく忘れるのが2番。テスト用のプロジェクトが参照しているのはdllなので、デバッガービジュアライザーのコードを修正したあとに、ビルドでdllを更新してからデバッグ開始ってことみたいねえ

 

 

ReleaseでビルドしたものをVisual Studioに追加

期待通りに動くようになったらReleaseでビルド

f:id:gogowaten:20200113164427p:plain

DebugからReleaseに変更してから

 

f:id:gogowaten:20200113164436p:plain

ビルド

 

f:id:gogowaten:20200113164446p:plain

出力ウィンドウで見るとdllの作成場所は

C:\Users\waten\Source\Repos\wpf_test2\MyVisualizer\MyVisualizer\bin\Release\MyVisualizer.dll

f:id:gogowaten:20200113164452p:plain

Releaseフォルダに作成される

 

f:id:gogowaten:20200113165333p:plain

ビルドできたらDebugに戻しておく

 


dllをVisual Studioに登録(コピペ)

登録する場所はドキュメントフォルダのVisual StudioフォルダのVisualizersフォルダ

今回はVisual Studio 2019に登録したいので

C:\Users\waten\Documents\Visual Studio 2019\Visualizers

ここにdllをコピー

f:id:gogowaten:20200113165139p:plain

Visualizersフォルダにdllをコピーしたところ、これで全て完了!

 

 

全然別のプロジェクトで確認

f:id:gogowaten:20200113165931p:plain

この記事の冒頭と同じように表示された!できた!!!!!!

表示できるのは

BitmapSource クラス
定義
名前空間:
System.Windows.Media.Imaging
アセンブリ:
PresentationCore.dll
派生
System.Windows.Interop.InteropBitmap
System.Windows.Media.Imaging.BitmapFrame
System.Windows.Media.Imaging.BitmapImage
System.Windows.Media.Imaging.CachedBitmap
System.Windows.Media.Imaging.ColorConvertedBitmap
System.Windows.Media.Imaging.CroppedBitmap
System.Windows.Media.Imaging.FormatConvertedBitmap
System.Windows.Media.Imaging.RenderTargetBitmap
System.Windows.Media.Imaging.TransformedBitmap
System.Windows.Media.Imaging.WriteableBitmap

docs.microsoft.com

より引用

 ここの派生にあるものなら表示できるはず

 

 

 

全体

  1. MyVisualizer_ソリューション
  2. ┣ConsoleApp1_テスト用プロジェクト
  3. ┃┗Program.cs
  4. ┗MyVisualizer_デバッガービジュアライザーのプロジェクト
  5.     ┣Class1.cs
  6.     ┗MyDialog.cs
  7.         ┣MyDialog
  8.         ┣MySource
  9.         ┗MyProxy

 

6    ┗MyDialog.cs_デバッガービジュアライザー

f:id:gogowaten:20200113191615p:plain

デバッガービジュアライザーの本体?

 

MyDialog.cs

using Microsoft.VisualStudio.DebuggerVisualizers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;


[assembly:System.Diagnostics.DebuggerVisualizer(
    typeof(MyVisualizer.MyDialog),
    typeof(MyVisualizer.MySource),
    Target =typeof(BitmapSource),
    Description = "🐭びっとまっぷそぉす🐭")]
namespace MyVisualizer
{
    // TODO: SomeType のインスタンスをデバッグするときに、このビジュアライザーを表示するために SomeType の定義に次のコードを追加します:
    // 
    //  [DebuggerVisualizer(typeof(MyDialog))]
    //  [Serializable]
    //  public class SomeType
    //  {
    //   ...
    //  }
    // 
    /// <summary>
    /// SomeType のビジュアライザーです。  
    /// </summary>
    public class MyDialog : DialogDebuggerVisualizer
    {
        protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
        {
            if (windowService == null)
                throw new ArgumentNullException("windowService");
            if (objectProvider == null)
                throw new ArgumentNullException("objectProvider");

            // TODO: ビジュアライザーを表示する目的のオブジェクトを取得します。
            //       objectProvider.GetObject() の結果をキャスト
            //       されるオブジェクトの型にキャストします。
            var data = (MyProxy)objectProvider.GetObject();

            //MyProxyからBitmapSourceを作成
            var source = BitmapSource.Create(data.Width, data.Height, 96, 96,
                PixelFormats.Bgra32, null, data.Pixels, data.Stride);

            //Bitmapを作成して、BitmapSourceのデータをコピペ
            var bmp = new Bitmap(data.Width, data.Height,
                System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            var bmpData = bmp.LockBits(
                new Rectangle(0, 0, bmp.Width, bmp.Height),
                System.Drawing.Imaging.ImageLockMode.ReadOnly,
                bmp.PixelFormat);
            source.CopyPixels(Int32Rect.Empty, bmpData.Scan0, bmpData.Height * bmpData.Stride, bmpData.Stride);
            bmp.UnlockBits(bmpData);

            var pictureBox = new PictureBox
            {
                Image = bmp,
                SizeMode = PictureBoxSizeMode.AutoSize
            };
            // TODO: オブジェクトのビューを表示します。
            //       displayForm をユーザー独自のカスタム フォームまたはコントロールで置き換えます。
            using (Form displayForm = new Form())
            {
                displayForm.Text = data.ToString();
                displayForm.Controls.Add(pictureBox);
                windowService.ShowDialog(displayForm);
            }
            bmp.Dispose();
            pictureBox.Dispose();
        }

        // TODO: ビジュアライザーをテストするために、次のコードをユーザーのコードに追加します:
        // 
        //    MyDialog.TestShowVisualizer(new SomeType());
        // 
        /// <summary>
        /// デバッガーの外部にホストすることにより、ビジュアライザーをテストします。
        /// </summary>
        /// <param name="objectToVisualize">ビジュアライザーに表示するオブジェクトです。</param>
        public static void TestShowVisualizer(object objectToVisualize)
        {
            //VisualizerDevelopmentHost visualizerHost = new VisualizerDevelopmentHost(objectToVisualize, typeof(MyDialog));
            VisualizerDevelopmentHost visualizerHost 
                = new VisualizerDevelopmentHost(objectToVisualize, typeof(MyDialog), typeof(MySource));
            visualizerHost.ShowVisualizer();
        }
    }

    public class MySource : VisualizerObjectSource
    {
        public override void GetData(object target, Stream outgoingData)
        {
            var source = (BitmapSource)target;
            var proxy = new MyProxy(source);
            base.GetData(proxy, outgoingData);
        }
    }


    /// <summary>
    /// BitmapSourceをシリアライズできる型に分解
    /// PixelFormatをBgra32に決め打ち方式用
    /// </summary>
    [Serializable]
    public class MyProxy
    {
        public int Width { get; private set; }
        public int Height { get; private set; }
        public int Stride { get; private set; }
        public byte[] Pixels { get; private set; }

        public MyProxy(BitmapSource source)
        {
            if (source.Format != PixelFormats.Bgra32)
            {
                source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
            }
            Width = source.PixelWidth;
            Height = source.PixelHeight;
            Stride = Width * 4;// (Width * source.Format.BitsPerPixel + 7) / 8;
            Pixels = new byte[Height * Stride];
            source.CopyPixels(new Int32Rect(0, 0, Width, Height), Pixels, Stride, 0);
        }
    }
}

 

3┃┗Program.cs

f:id:gogowaten:20200113192505p:plain

テスト用

 

5    ┣Class1.cs

f:id:gogowaten:20200113192601p:plain

使っていないので初期状態のまま

ソリューションエクスプローラ

f:id:gogowaten:20200113192926p:plain

この配置

 

参照した主なところ

夕暮ログ

夕暮ログ デバッガビジュアライザ(2)基本的な作り方

夕暮ログ デバッガビジュアライザを追加するのと同じことをする

夕暮ログ シリアライズできないクラスをデバッガビジュアライザでデバッグする

夕暮ログ 【ビジュアライザ】シリアライズできないクラスをプロクシクラスを通してデバッグ

夕暮ログ 【ビジュアライザ】プロクシクラスから置き換える

かなり詳しく丁寧に解説なさっている、ここがなかったら今回のはできなかった

 

方法: ビジュアライザーをインストールする - Visual Studio | Microsoft Docs

 

 

schima.hatenablog.com

シリアライズできない型の対処法はここが簡潔でわかりやすかった

 

blogs.microsoft.co.il

今回は使わなかったけどPixelFormatをシリアライズする方法がある

BitmapSourceのまま表示する方法も書いてあるけど、これは読んでもわからなかった…コードも公開されていたようだけど、今はなくなっているみたい、もったいない

 

qiita.com

BitmapSourceからBitmapへの変換はこちらから






完走した感想

こんなに難しいとは思わなかった、WPFを触り始めたときにも作ろうとしたけど諦めた記憶があって、いつかできたらいいなあと思いつつ4年くらい経ったのかな?ようやくできた!諦めと今じゃなくていつかできたらいいなあってのは大事だねえ、ふと思い立って"デバッガービジュアライザー WPF BitmapSource"とかでググったら、やっぱりわからなくて特にオーバライドしたGetDataをどこから呼んだらいいのかと、PixelFormatのシリアライズ…は今回は使わなかったけど、この辺が時間かかったけど4日くらいでできて、確認のためにもう一度最初から作ったらdllのバージョンが違うとかのわけのわからんエラーが出て、これは結局バージョン違いじゃなくてビルドの順番かなんかがおかしかったのか、ビルドのクリーンとかリビルドとかそのへんをいじっていたら直って、わけわからんと思いつつ、この記事を書きながらまた一から作っていったんだけど、普通に動くのができてよかったわ

WPFをそのまま表示できればかなりラクなんだけどデバッガービジュアライザーはFormだけみたいなんだよねえ、FormにWPFの要素を表示できるようにするElementHostっていうのがFormのコントロールにあるみたいで、これも試してみたんだけど

 

f:id:gogowaten:20200113200015p:plain

WPFのユーザーコントロール

Imageを置いただけのWindow

これのコードは

f:id:gogowaten:20200113200336p:plain

受け取ったBitmapSourceをImageのSourceプロパティに指定するだけのもの、このユーザーコントロール

 

f:id:gogowaten:20200113200426p:plain

デバッガービジュアライザーのほうで使うようにしてみたけどエラーになる

133行目でElementHost作成して、そのChildプロパティにユーザーコントロールを指定して、これをFormのControlsに指定していて、エラーになる場所はユーザーコントロールを作成するところなんだけど、これはもうわからん、これができればBitmapSourceからBitmapへの変換が必要なくなるし、WPFの要素もそのまま使えるっぽいからいいんだけどねえ、わからん

 

あとは拡大とか保存とかの機能をつけたい

dpiも96で決め打ちしているのもProxyに加えたほうがいいかなあ

 

 

 

 

関連記事

gogowaten.hatenablog.com

 

 次回

gogowaten.hatenablog.com

 

 2ヶ月後

gogowaten.hatenablog.com