如何获得“可见"画布的尺寸? [英] How to get "visible" size of canvas?

查看:42
本文介绍了如何获得“可见"画布的尺寸?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将 Canvas 的可见内容保存为 PNG.

I need to save visible content of Canvas as PNG.

我有以下方法,可以获取 Canvas 的实际大小并将其保存为图像.

I have the folowing method that takes actual size of Canvas and save it as image.

        private void SavePng()
        {
            Rect bounds = VisualTreeHelper.GetDescendantBounds(this.CanvasMain);
            
            //I also tried this
            /*Rect bounds = new Rect(
                  new Point(0, 0), 
                  new Point(this.CanvasMain.ActualWidth, this.CanvasMain.ActualHeight)
              );*/        
    
            double dpi = 96d;

            RenderTargetBitmap rtb = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, dpi, dpi, System.Windows.Media.PixelFormats.Default);

            DrawingVisual dv = new DrawingVisual();
            using (DrawingContext dc = dv.RenderOpen())
            {
                VisualBrush vb = new VisualBrush(this.CanvasMain);
                dc.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
            }

            rtb.Render(dv);

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

            try
            {
                System.IO.MemoryStream ms = new System.IO.MemoryStream();

                pngEncoder.Save(ms);
                ms.Close();

                SaveFileDialog dlg = new SaveFileDialog();
                dlg.DefaultExt = ".png";
                dlg.Filter = "Image (.png)|*.png";
                string filename = "";
                if (dlg.ShowDialog() == true)
                    filename = dlg.FileName;

                System.IO.File.WriteAllBytes(filename, ms.ToArray());
            }
            catch (ArgumentException err)
            {
                MessageBox.Show("Wrong path!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

但是如果我有一个超出窗口边界的对象,我会得到这样的结果:

But if I have an object out of bounds of the window, I will get something like this:

如何只获取窗口边界内的 Canvas 可见部分?

How do I get only the visible part of the Canvas that is within the bounds of the window?

推荐答案

VisualBrush 自动确定其渲染内容"的边界.

A VisualBrush automatically determines the bounds of its "rendered content".

为了避免这种情况,请设置其 Viewbox 属性:

In order to avoid that, set its Viewbox property:

var rect = new Rect(CanvasMain.RenderSize);

var rtb = new RenderTargetBitmap(
    (int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default);

var dv = new DrawingVisual();

using (var dc = dv.RenderOpen())
{
    var vb = new VisualBrush
    {
        Visual = CanvasMain,
        Viewbox = rect,
        ViewboxUnits = BrushMappingMode.Absolute
    };

    dc.DrawRectangle(vb, null, rect);
}

rtb.Render(dv);

或者,将 Canvas 的 ClipToBounds 属性设置为 true:

Alternatively, set the Canvas's ClipToBounds property to true:

<Canvas x:Name="CanvasMain" ClipToBounds="True" ...>

这篇关于如何获得“可见"画布的尺寸?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆