这是一个分为两部分的问题-首先,为什么该代码不起作用?

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。 Canvas在代码中使用Shapes(折线等)进行绘制。然后,我需要以每秒约60帧的速率将此BitmapSource传递给xaml中的Image。我注意到,如果创建模拟BitmapSource,则Image.Source将使用CachedBitmap,但每次更新(黑色)Bitmap时,Image.Source都会重新绑定到BitmapImage。

有关如何以60fps的速度在内存中创建Canvas并从中创建Image.Source视为CachedBitmap的BitmapSource的建议?

最佳答案

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;
}

关于wpf - 将WPF控件转换为BitmapSource,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6688262/

10-10 21:43