如何在中间没有线条的情况下使刷子光滑

HB *_*AAM 6 c# wpf blend

在此输入图像描述

大家好,正如你在之前的画笔中看到的那样,中间有线条,
如何使它平滑是不是很顺利?(如何删除那些行)我用混合创建它

<Grid x:Name="LayoutRoot">
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.452,1.962" StartPoint="1.164,-0.352">
                <GradientStop Color="#FF202020" Offset="0"/>
                <GradientStop Color="#FF545454" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>
    </Grid>
Run Code Online (Sandbox Code Playgroud)

Chr*_*isF 10

条带是梯度算法的假象.它必须打破区域,每个区域都填充略有不同的颜色.边缘实际上是一种视错觉,其效果使它们比您想象的更加明显.要减少这种影响,您需要减小每个波段的宽度.

解决方案是:

  1. 填充较小的区域 - 每个波段较窄.
  2. 增加乐队数量.使两个极端之间的对比更大.
  3. 增加显示器的颜色分辨率.如果您有更多颜色可供选择,那么两种最终颜色之间的可用范围将更大.

我确实意识到这些解决方案要么a)不可能,要么b)不实用.这是一个你不得不忍受的问题.

一个实用的解决方案可能是用Photoshop或其他图像处理包中创建的图像替换画笔.这可能会给你一个带有较少条带的图像 - 但是你被限制在图像的大小 - 如果没有像素化你就无法生长它.


gho*_*ord 8

前段时间我为WPF项目编写了平滑的线性渐变.它删除了条带,但有两个警告:

  • 它不能用于数据绑定颜色或{DynamicResource}.
  • 它目前仅支持垂直渐变,因为这就是我所需要的

ImageBrush使用Ordered Dithering实现动态创建.另外,它也是一个MarkupExtension,因为人们不能简单地继承任何Brush类(这些都是密封的).

/// <summary>
/// Brush that lets you draw vertical linear gradient without banding.
/// </summary>
[MarkupExtensionReturnType(typeof(Brush))]
public class SmoothLinearGradientBrush : MarkupExtension
{
    private static PropertyInfo dpiX_;
    private static PropertyInfo dpiY_;
    private static byte[,] bayerMatrix_ = 
    {
        { 1, 9, 3, 11 },
        { 13, 5, 15, 7 },
        { 1, 9, 3, 11 },
        { 16, 8, 14, 6 }
    };

    static SmoothLinearGradientBrush()
    {
        dpiX_ = typeof(SystemParameters).GetProperty("DpiX", BindingFlags.NonPublic | BindingFlags.Static);
        dpiY_ = typeof(SystemParameters).GetProperty("Dpi", BindingFlags.NonPublic | BindingFlags.Static);
    }

    /// <summary>
    /// Gradient color at the top
    /// </summary>
    public Color From { get; set; }

    /// <summary>
    /// Gradient color at the bottom
    /// </summary>
    public Color To { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        //If user changes dpi/virtual screen height during applicaiton lifetime,
        //wpf will scale the image up for us.
        int width = 20;
        int height = (int)SystemParameters.VirtualScreenHeight;
        int dpix = (int)dpiX_.GetValue(null);
        int dpiy = (int)dpiY_.GetValue(null);


        int stride = 4 * ((width * PixelFormats.Bgr24.BitsPerPixel + 31) / 32);

        //dithering parameters
        double bayerMatrixCoefficient = 1.0 / (bayerMatrix_.Length + 1);
        int bayerMatrixSize = bayerMatrix_.GetLength(0);

        //Create pixel data of image
        byte[] buffer = new byte[height * stride];

        for (int line = 0; line < height; line++)
        {
            double scale = (double)line / height;

            for (int x = 0; x < width * 3; x += 3)
            {
                //scaling of color
                double blue = ((To.B * scale) + (From.B * (1.0 - scale)));
                double green = ((To.G * scale) + (From.G * (1.0 - scale)));
                double red = ((To.R * scale) + (From.R * (1.0 - scale)));

                //ordered dithering of color
                //source: http://en.wikipedia.org/wiki/Ordered_dithering
                buffer[x + line * stride] = (byte)(blue + bayerMatrixCoefficient * bayerMatrix_[x % bayerMatrixSize, line % bayerMatrixSize]);
                buffer[x + line * stride + 1] = (byte)(green + bayerMatrixCoefficient * bayerMatrix_[x % bayerMatrixSize, line % bayerMatrixSize]);
                buffer[x + line * stride + 2] = (byte)(red + bayerMatrixCoefficient * bayerMatrix_[x % bayerMatrixSize, line % bayerMatrixSize]);
            }
        }

        var image = BitmapSource.Create(width, height, dpix, dpiy, PixelFormats.Bgr24, null, buffer, stride);
        image.Freeze();
        var brush = new ImageBrush(image);
        brush.Freeze();
        return brush;
    }
}
Run Code Online (Sandbox Code Playgroud)

资源字典中的用法:

<local:SmoothLinearGradientBrush x:Key="WindowBackgroundBrush" 
                                 From="{StaticResource WindowBackgroundColorLight}" 
                                 To="{StaticResource WindowBackgroundColorDark}" />
Run Code Online (Sandbox Code Playgroud)

然后是控制风格:

<Style ...>
    <Setter Property="Background" Value="{StaticResource WindowBackgroundBrush}" />
</Style>
Run Code Online (Sandbox Code Playgroud)