3

これは一種の 2 つの部分からなる質問です。まず、このコードが機能しないのはなぜですか?

Canvas canvas = new Canvas { Width = 640, Height = 480 };
System.Windows.Size size = new System.Windows.Size( canvas.Width, canvas.Height);

//Measure and arrange the surface
canvas.Measure( size );
canvas.Arrange( new Rect( size ) );

canvas.Background = new SolidColorBrush( Colors.Purple );

RenderTargetBitmap bitmap = new RenderTargetBitmap( (int)canvas.Width, (int)canvas.Height, 96d, 96d, PixelFormats.Pbgra32 );
bitmap.Render( canvas );
BitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add( BitmapFrame.Create( bitmap ) );

using ( MemoryStream outStream = new MemoryStream() )
{
    encoder.Save( outStream );

    outStream.Seek( 0, SeekOrigin.Begin );
    BitmapImage bmp = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
    bmp.BeginInit();
    bmp.StreamSource = outStream;
    bmp.EndInit();
}

画像をディスクに書き込むと、黒い画像しか表示されません。以前にこれを行ったことがあり、問題はありませんでしたが、今は何かが私を逃れています...幅と高さ、およびバッファデータを確認しましたMemoryStream とすべてが問題ないように見えます...

これは単なるテストです。実際の目標は、Canvas ビジュアル イメージから BitmapSource を作成することです。キャンバスは、コード内の形状 (ポリラインなど) で描画されています。次に、この BitmapSource を xaml の Image に 1 秒あたり約 60 フレームの速度で渡す必要があります。モック BitmapSource を作成すると Image.Source が CachedBitmap を使用していることに気付きましたが、(黒の) ビットマップを更新するたびに BitmapImage に再バインドされます。

60fps でメモリ内に Canvas を作成し、Image.Source から CachedBitmap として表示される BitmapSource を作成する方法に関する提案はありますか?

4

2 に答える 2

0

Makubexは正しいです-ビジュアルが実際にコピー可能なものをレンダリングした状態になる前に、物がロードされるまで待つ必要があります。そうは言っても、Studioがインストールされているコンピューターを使用していないときは、LINQPadがインストールされています。

void Main()
{   
    mainWindow = new Window(){ Width = 640, Height = 480, Title = "Main Window" };
    canvas = new Canvas { Width = 640, Height = 480 };
    System.Windows.Size size = new System.Windows.Size( canvas.Width, canvas.Height );
    // Measure and arrange the surface
    canvas.Measure( size );
    canvas.Arrange( new Rect( size ) );
    canvas.Background = new SolidColorBrush( Colors.Purple );   

    mirrorTimer = new DispatcherTimer(
        TimeSpan.FromMilliseconds(1000.0 / 60.0), 
        DispatcherPriority.Background, 
        CopyToMirror, 
        Dispatcher.CurrentDispatcher);
    updateTimer = new DispatcherTimer(
        TimeSpan.FromMilliseconds(1000.0 / 60.0), 
        DispatcherPriority.Background, 
        DrawSomething, 
        Dispatcher.CurrentDispatcher);

    mainWindow.Loaded += 
        (o,e) => 
        {
            mirrorWindow = new Window { Width = 640, Height = 480, Title = "Mirror Window" };
            mirrorWindow.Show();
            mirrorWindow.Loaded += 
                (o2,e2) => 
                { 
                    mirrorTimer.Start(); 
                };          
        };
    mainWindow.Closed += 
        (o,e) => 
        { 
            if(mirrorTimer != null) 
            {
                mirrorTimer.Stop();
                mirrorWindow.Close();
            }
        };
    mainWindow.Content = canvas;
    mainWindow.Show();  
}

Window mainWindow;
Window mirrorWindow;
Canvas canvas;
DispatcherTimer mirrorTimer;
DispatcherTimer updateTimer;
Random rnd = new Random();

private void DrawSomething(object sender, EventArgs args)
{
    canvas.Children.Clear();
    canvas.Background = Brushes.White;
    var blob = new Ellipse() { Width = rnd.Next(0, 20), Height = rnd.Next(0, 20) };
    blob.Fill = new SolidColorBrush(Color.FromArgb(255, (byte)rnd.Next(0,255), (byte)rnd.Next(0,255), (byte)rnd.Next(0,255)));
    Canvas.SetLeft(blob, (int)rnd.Next(0, (int)canvas.ActualWidth));
    Canvas.SetTop(blob, (int)rnd.Next(0, (int)canvas.ActualHeight));
    canvas.Children.Add(blob);
}

private void CopyToMirror(object sender, EventArgs args)
{       
    var currentImage = (mirrorWindow.Content as Image);
    if(currentImage == null)
    {
        currentImage = new Image(){ Width = 640, Height = 480 };
        mirrorWindow.Content = currentImage;
    }

    RenderTargetBitmap bitmap = new RenderTargetBitmap( (int)canvas.Width, (int)canvas.Height, 96d, 96d, PixelFormats.Pbgra32 );
    bitmap.Render( canvas );
    BitmapEncoder encoder = new BmpBitmapEncoder();
    encoder.Frames.Add( BitmapFrame.Create( bitmap ) );

    BitmapImage bmp = new BitmapImage() { CacheOption = BitmapCacheOption.OnLoad };
    MemoryStream outStream = new MemoryStream();
    encoder.Save(outStream);
    outStream.Seek(0, SeekOrigin.Begin);
    bmp.BeginInit();
    bmp.StreamSource = outStream;
    bmp.EndInit();      
    currentImage.Source = bmp;  
}
于 2012-11-15T02:51:13.037 に答える
0

黒い画像にまだ問題がある場合は、 CacheOption の設定を BeingInit 呼び出しの直後に移動します。

bmp.BeginInit();
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.StreamSource = outStream;
bmp.EndInit();
于 2014-07-02T20:14:34.157 に答える