从 WPF 中提取剪辑 Canvas
Extract Clip from WPF Canvas
我在尝试不仅剪辑而且“提取”WPF 的一部分时遇到问题 Canvas。所以基本上我希望“剪辑”扩展到 window 的完整大小,或者将剪辑的项目转换为单独的 UI 元素以导出到 PNG。我写伪代码是因为真正的代码来自 Autocad 模型。
double oPrintWidth=1169;
Canvas c = new Canvas();
c.Width = oPrintWidth * 2.54;
c.Height = c.Width * ratio;
// Define the path to clip
string thisPathData = "M12233 M222333 M3443" // fake
c.Clip = Geometry.Parse(thisPathData);
此时我有相同的大小 canvas 但除了我的路径之外的所有内容现在都是黑色的。而且路径还在原来的位置。我现在需要将剪辑制作成整个 canvas.
我玩过 RenderTransform 但我不知道下一步该做什么,我不太擅长矩阵计算。
原创 Canvas(UI 元素的集合)
剪辑后
期望的结果
最终会打印出来,但更愿意将其保留在 WPF 中直到最后一分钟,以保留 VECTOR 属性以转换为 SVG/XPS/ETC
要制作整个 Canvas
的 Clip
,然后将 Clip
应用到 Canvas
,我建议您让 WPF 为您设置 ClipToBounds
属性:
Canvas c = new Canvas();
c.ClipToBounds = true;
如果这不符合您的需要,我会查看 Margin
、ActualWidth
和 ActualHeight
属性来确定剪辑区域。然后创建一个与 Canvas
.
大小匹配的 RectangleGeometry
根据您的评论进行编辑。
好吧,我还有一些时间来处理它。我能够做的是创建一个剪辑区域,然后我转换 canvas 以便剪辑区域尽可能多地填充 canvas。我想这就是你想要的...
首先我需要测量裁剪区域:
Rect bounds = canvas.Clip.Bounds;
double scaleX = c.Width / (bounds.Right - bounds.Left);
double scaleY = c.Height / (bounds.Bottom - bounds.Top);
此缩放信息用于使裁剪区域完全适合 canvas 的大小。
现在,我们需要将转换应用于 canvas:
TransformGroup group = new TransformGroup();
TranslateTransform move = new TranslateTransform(-bounds.Left, -bounds.Top);
ScaleTransform scale = new ScaleTransform(scaleX, scaleY);
group.Children.Add(move);
group.Children.Add(scale);
canvas.RenderTransform = group;
那么这里发生了什么?首先,objective 是应用几个转换。我们需要将裁剪区域居中(平移)并且我们需要使裁剪区域更大(缩放)。现在,当我说裁剪区域时,我指的是该区域的内容。实际上,我们正在移动 canvas 的渲染输出。移动区域边界不是我们想要做的。
要在 WPF 中执行此操作,我们需要将我们想要的每个转换添加到 TransformGroup
的子级。
在这种情况下,我们正在翻译 canvas 的输出,使其左上角为 (0, 0)
这是必要的,因为之后我们将缩放渲染输出。所以,现在,我们需要缩放 canvas 的输出,使图像尽可能大。为此,我们需要创建一个比率,将 canvas 大小与裁剪区域大小进行比较。
这里是缩放输出的公式:
ratio = canvasSize / clippedSize
scaledSize = clippsedSize * ratio
现在,缩放 canvas 的输出将使裁剪区域看起来尽可能大。
看看结果。以下图片展示了应用转换前后 canvas 的输出:
之前
之后
我想我不妨把我用过的所有代码都给你:
Canvas c = new Canvas();
double oPrintWidth=100;
double ratio = .89;
c.Width = oPrintWidth * 2.54;
c.Height = c.Width * ratio;
c.Background = new ImageBrush((ImageSource)FindResource("TestImage")) { Stretch = Stretch.UniformToFill };
// Define the path to clip
string newPath = "M 64,64 L 64,128 128,128, 128,64 Z";
c.Clip = Geometry.Parse(newPath);
Rect bounds = c.Clip.Bounds;
double scaleX = c.Width / (bounds.Right - bounds.Left);
double scaleY = c.Height / (bounds.Bottom - bounds.Top);
TransformGroup group = new TransformGroup();
TranslateTransform move = new TranslateTransform(-bounds.Left, -bounds.Top);
ScaleTransform scale = new ScaleTransform(scaleX, scaleY);
group.Children.Add(move);
group.Children.Add(scale);
c.RenderTransform = group;
MyBorder.Child = c;
和 XAML:
<Window.Resources>
<BitmapImage UriSource="uvtest.jpg" x:Key="TestImage"/>
</Window.Resources>
<Grid Background="Gray">
<Border x:Name="MyBorder" Background="White" BorderBrush="Black" BorderThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
我在尝试不仅剪辑而且“提取”WPF 的一部分时遇到问题 Canvas。所以基本上我希望“剪辑”扩展到 window 的完整大小,或者将剪辑的项目转换为单独的 UI 元素以导出到 PNG。我写伪代码是因为真正的代码来自 Autocad 模型。
double oPrintWidth=1169;
Canvas c = new Canvas();
c.Width = oPrintWidth * 2.54;
c.Height = c.Width * ratio;
// Define the path to clip
string thisPathData = "M12233 M222333 M3443" // fake
c.Clip = Geometry.Parse(thisPathData);
此时我有相同的大小 canvas 但除了我的路径之外的所有内容现在都是黑色的。而且路径还在原来的位置。我现在需要将剪辑制作成整个 canvas.
我玩过 RenderTransform 但我不知道下一步该做什么,我不太擅长矩阵计算。
原创 Canvas(UI 元素的集合)
剪辑后
期望的结果
最终会打印出来,但更愿意将其保留在 WPF 中直到最后一分钟,以保留 VECTOR 属性以转换为 SVG/XPS/ETC
要制作整个 Canvas
的 Clip
,然后将 Clip
应用到 Canvas
,我建议您让 WPF 为您设置 ClipToBounds
属性:
Canvas c = new Canvas();
c.ClipToBounds = true;
如果这不符合您的需要,我会查看 Margin
、ActualWidth
和 ActualHeight
属性来确定剪辑区域。然后创建一个与 Canvas
.
RectangleGeometry
根据您的评论进行编辑。
好吧,我还有一些时间来处理它。我能够做的是创建一个剪辑区域,然后我转换 canvas 以便剪辑区域尽可能多地填充 canvas。我想这就是你想要的...
首先我需要测量裁剪区域:
Rect bounds = canvas.Clip.Bounds;
double scaleX = c.Width / (bounds.Right - bounds.Left);
double scaleY = c.Height / (bounds.Bottom - bounds.Top);
此缩放信息用于使裁剪区域完全适合 canvas 的大小。 现在,我们需要将转换应用于 canvas:
TransformGroup group = new TransformGroup();
TranslateTransform move = new TranslateTransform(-bounds.Left, -bounds.Top);
ScaleTransform scale = new ScaleTransform(scaleX, scaleY);
group.Children.Add(move);
group.Children.Add(scale);
canvas.RenderTransform = group;
那么这里发生了什么?首先,objective 是应用几个转换。我们需要将裁剪区域居中(平移)并且我们需要使裁剪区域更大(缩放)。现在,当我说裁剪区域时,我指的是该区域的内容。实际上,我们正在移动 canvas 的渲染输出。移动区域边界不是我们想要做的。
要在 WPF 中执行此操作,我们需要将我们想要的每个转换添加到 TransformGroup
的子级。
在这种情况下,我们正在翻译 canvas 的输出,使其左上角为 (0, 0)
这是必要的,因为之后我们将缩放渲染输出。所以,现在,我们需要缩放 canvas 的输出,使图像尽可能大。为此,我们需要创建一个比率,将 canvas 大小与裁剪区域大小进行比较。
这里是缩放输出的公式:
ratio = canvasSize / clippedSize
scaledSize = clippsedSize * ratio
现在,缩放 canvas 的输出将使裁剪区域看起来尽可能大。
看看结果。以下图片展示了应用转换前后 canvas 的输出:
之前
之后
我想我不妨把我用过的所有代码都给你:
Canvas c = new Canvas();
double oPrintWidth=100;
double ratio = .89;
c.Width = oPrintWidth * 2.54;
c.Height = c.Width * ratio;
c.Background = new ImageBrush((ImageSource)FindResource("TestImage")) { Stretch = Stretch.UniformToFill };
// Define the path to clip
string newPath = "M 64,64 L 64,128 128,128, 128,64 Z";
c.Clip = Geometry.Parse(newPath);
Rect bounds = c.Clip.Bounds;
double scaleX = c.Width / (bounds.Right - bounds.Left);
double scaleY = c.Height / (bounds.Bottom - bounds.Top);
TransformGroup group = new TransformGroup();
TranslateTransform move = new TranslateTransform(-bounds.Left, -bounds.Top);
ScaleTransform scale = new ScaleTransform(scaleX, scaleY);
group.Children.Add(move);
group.Children.Add(scale);
c.RenderTransform = group;
MyBorder.Child = c;
和 XAML:
<Window.Resources>
<BitmapImage UriSource="uvtest.jpg" x:Key="TestImage"/>
</Window.Resources>
<Grid Background="Gray">
<Border x:Name="MyBorder" Background="White" BorderBrush="Black" BorderThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>