快速生成带状图像?

时间:2015-02-24 23:43:09

标签: c# .net wpf image

我需要生成墙的预览图像以便动态显示。所有这些都将由不同颜色和宽度的乐队组成,应该看起来像这样:

sample wall

现在我有它的工作,但它有点慢(不是很糟糕,但足够让人觉得有点滞后),我想知道是否有更好的方法。

我目前正在做的是在代码中构建wpf对象。我构建一个网格作为主要容器,然后是一个预览的堆栈面板,然后是一个底部有标签的文本块(从这个图像裁剪出来,抱歉),然后我为每个图层添加边框对象(band )具有轮廓的边框粗细和适当的颜色作为背景等。然后我使用

        RenderTargetBitmap bmp = new RenderTargetBitmap((int)gd.ActualWidth, (int)gd.ActualHeight, 96, 96, PixelFormats.Pbgra32);
        bmp.Render(gd);

其中gd是保存堆栈面板和文本块的网格对象,然后将其用作图像源。

我使用图像源而不是直接使用WPF对象的原因有两个。首先,我有其他对象是需要加载和预览的实际图像文件,因此它们来自图像源,而不是WPF视觉。其次,我有一个缩略图和一个完整的预览。我希望能够将缩略图显示为预览的缩小版本,如果它是wpf对象我不认为你可以做到(至少不容易)。

无论如何,如果有人有更好的方法做到这一点,我一定会很感激...

2 个答案:

答案 0 :(得分:2)

  

如果有人有更好的方法来做到这一点我肯定会感激...

你可以创建你的墙'模式'在LinearGradientBrush中使用简单的Rectangle非常容易。这是您显示的模式的近似值:

<Border BorderBrush="#FF393939" BorderThickness="10" Background="Black" Padding="2">
    <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <Rectangle.Fill>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                <GradientStop Offset="0" Color="#FFAA6268" />
                <GradientStop Offset="0.195" Color="#FFAA6268" />
                <GradientStop Offset="0.196" Color="#FF8B8B8B" />
                <GradientStop Offset="0.204" Color="#FF8B8B8B" />
                <GradientStop Offset="0.205" Color="#FFE3E3E3" />
                <GradientStop Offset="0.395" Color="#FFE3E3E3" />
                <GradientStop Offset="0.396" Color="#FF6F6F6F" />
                <GradientStop Offset="0.404" Color="#FF6F6F6F" />
                <GradientStop Offset="0.405" Color="#FFFF" />
                <GradientStop Offset="0.595" Color="#FFFF" />
                <GradientStop Offset="0.596" Color="#FF555555" />
                <GradientStop Offset="0.604" Color="#FF555555" />
                <GradientStop Offset="0.605" Color="#FFD4B371" />
                <GradientStop Offset="0.665" Color="#FFD4B371" />
                <GradientStop Offset="0.666" Color="#FF555555" />
                <GradientStop Offset="0.674" Color="#FF555555" />
                <GradientStop Offset="0.675" Color="#FFC7C7C7" />
                <GradientStop Offset="0.97" Color="#FFC7C7C7" />
                <GradientStop Offset="0.98" Color="#FF5E5E5E" />
                <GradientStop Offset="1.0" Color="#FF5E5E5E" />
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
</Border>

此XAML创建此输出:

enter image description here

请记住,这可以在代码方法中非常容易地生成,在那里您可以更好地控制每条线的厚度,而我只是粗略地估计了这一点。另请注意,每个颜色/行需要两个 GradientStop ...开头结束偏移。


更新&gt;&gt;&gt;

我无法真实地告诉您如何使用图片,但在此可能值得注意的是,您也可以使用图片绘制Rectangle s:

<Border BorderBrush="#FF393939" BorderThickness="10" Background="Black" Padding="2">
    <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <Rectangle.Fill>
            <VisualBrush Stretch="Uniform">
                <VisualBrush.Visual>
                    <Image Source="pack://application:,,,/WpfApplication2;component/Images/Image.png" />
                </VisualBrush.Visual>
            </VisualBrush>
        </Rectangle.Fill>
    </Rectangle>
</Border>

答案 1 :(得分:0)

好的,所以我最终做的事情是通过其中的几个,并且似乎工作得很好。

在考虑了像@HighCore建议的数据模板之后,我意识到我可以使用ContentTemplateSelector类来确定单独的模板,这些模板应该是一个位图还是像这样自动生成的项目。然后,我为所需的每种预览类型类型创建了标准XAML模板,并将它们提供给模板选择器。

由于我已经有了为分层预览生成WPF可视元素的代码,我做了一些分析,并发现(毫不奇怪)生成位图是绝大部分所需的时间。然后我在我的视图模型上创建了一个属性,它返回了我生成的WPF元素,并使模板正确绑定到预览的内容源。

另一个可能对某人有帮助的重要事情是我发现了以前从未使用过的ViewBox类。这正是我所说的缩放WPF元素以适应盒子。我的缩略图模板是一个具有特定大小的视图框,其中Stretch =&#34; Uniform&#34;。视图框内的内容是wpf元素或图像。在完整尺寸版本中,我也使用了一个视图框,但只设置了一个最大尺寸(这样如果内容超过最大尺寸,它将自动缩小)。

希望有人帮助......