【问题标题】:Generate banded image quickly?快速生成带状图像?
【发布时间】:2015-02-24 23:43:09
【问题描述】:

我需要生成墙壁的预览图像以动态显示。它们都由不同颜色和宽度的条带组成,看起来应该像这样:

现在我可以使用它,但它有点慢(并不可怕,但足以让人感觉有点滞后),我想知道是否有更好的方法。

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

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

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

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

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

【问题讨论】:

  • 如果我误会了,我很抱歉,但我认为这根本不能解决我的问题。如果这是一个静态的层数,那么我可以使用 XAML 并且很乐意这样做,但它可能是从一层到理论上无限的层(实际上可能不超过 10 层)。您将如何设置 XAML 代码来处理它?如果我这样做了,那我在哪里有图像呢?我有多个对象(数十万个),并且以这种方式生成了一些预览,而有些则加载了实际的图像文件。另外,您如何动态缩放以适应缩略图?
  • 为了清楚起见,我很想使用纯 XAML 并按照您的建议使用 WPF 图形获得我想要的东西,我只是不确定如何去做,而且您的评论没有具体要弄清楚如何做到这一点......
  • How would you set up XAML code to handle that? - 通过使用 ItemsControl 和适当的 DataTemplates。删除所有代码并开始阅读herehere。基本上,WPF 中所有基于项目的 UI 都是使用 ItemsControl 完成的,无论它们的视觉外观如何。
  • 关于缩放,我已经告诉过你WPF会自动缩放,不用担心。
  • 我不知道为什么没有人提到你可以用LinearGradientBrushRectangle 来创建那个“图像”...绝对不需要BitMapImages或Images。

标签: c# .net wpf image


【解决方案1】:

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

您可以在Rectangle 中使用简单的LinearGradientBrush 轻松创建墙“图案”。这是您显示的模式的近似值:

<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 创建此输出:

请记住,这可以很容易地在代码方法中生成,您可以更好地控制每条线的粗细,而我只是粗略估计。另请注意,对于每种颜色/线条,您需要 两个 GradientStops...开始结束偏移。


更新>>>

我不知道你是如何使用你的图片的,但在这里可能值得注意的是,你也可以用图片来绘制Rectangles:

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

【讨论】:

  • 有趣的方法,我没想到。然而,使用一组动态图层似乎真的很难......不过要记住的创造性方式......
  • 实际上,我想说以编程方式进行比在 XAML 中进行更容易。每行有两个偏移量,总宽度 = 1.0。一点点数学就可以计算出每一行的确切位置。
  • 我想是的。但是,我已经有了计算堆叠边界的方法,所以对我来说使用它更容易:)。这仍然无法解决使用加载的图像文件的问题,因此我无法将其标记为答案,但我赞成,因为它是非常有用和有创意的解决方案,需要牢记...
【解决方案2】:

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

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

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

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

希望对某人有所帮助...

【讨论】:

    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2016-09-04
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多