C#WPF将画布动态保存为包含其子画面的图像

时间:2013-01-03 12:39:26

标签: c# .net wpf canvas

我是wpf开发的新手。我在运行时动态地在画布中添加了一个图像,我试图保存该图像容器,即画布作为png图像。但我没有正确得到输出图像。我得到一张空白的png图像。任何人都可以告诉我的代码逻辑有什么问题。

代码

private void CreateSaveBitmap1(string filename, Rect rect)
{
    System.Windows.Controls.Image bg = new System.Windows.Controls.Image();
    bg.Source = new BitmapImage(new Uri(filename, UriKind.Relative));


    Canvas imageCan = new Canvas();
    imageCan.Height = 800;
    imageCan.Width = 1000;

    Canvas.SetLeft(bg, 0);
    Canvas.SetTop(bg, 0);

    bg.RenderTransform = trGrp; //trGrp is the TransformGroup object.


    RenderTargetBitmap rtb = new RenderTargetBitmap((int)imageCan.Width, (int)imageCan.Height, 96d, 96d, System.Windows.Media.PixelFormats.Default);
    rtb.Render(imageCan);


    //var crop = new CroppedBitmap(rtb, new Int32Rect((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));            

    BitmapEncoder pngEncoder = new PngBitmapEncoder();
    pngEncoder.Frames.Add(BitmapFrame.Create(rtb));

    using (var fs = System.IO.File.OpenWrite(@"D:\test\nowTest.png"))
    {
        pngEncoder.Save(fs);
    }
}

3 个答案:

答案 0 :(得分:1)

您应该通过调用UpdateLayoutInvalidateVisual来强制执行画布的初始布局:

imageCan.UpdateLayout();

RenderTargetBitmap rtb = ...
rtb.Render(imageCan);

可能需要通过设置BitmapCacheOption.OnLoad

强制立即加载图像
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(filename, UriKind.Relative);
image.EndInit();
bg.Source = image;

答案 1 :(得分:0)

我遇到过类似的问题 它不仅会影响RenderTargetBitmap,还会影响XPS和PDF输出。 不幸的是,真正对我有用的唯一方法有点难看:
我不得不将它添加到可视树中并调用更新布局。

意思是我在窗口的某个地方有一个画布,添加了它,名为UpdateLayout,创建了导出并随后将其删除了

其他一切(例如克莱门斯所说的)都行不通。所以这个解决方案非常难看,但至少它以某种方式起作用。

答案 2 :(得分:0)

您应该更新画布布局

使用UpdateLayout方法:     MyCanvas.UpdateLayout();

此外,您应该检查画布高度和风度必须大于0;