LinearGradientBrush 导致非平滑渐变位图
LinearGradientBrush results in non-smooth gradient bitmap
我正在使用此函数生成一个简单的渐变位图,使用 LinearGradientBrush
我最后将其另存为文件以用作墙纸。但问题是结果看起来并不“平滑”,它看起来相当“断断续续”,因为你可以看到颜色的线条。
我使用屏幕边界作为位图的尺寸,增加尺寸并不能提高质量(我试过 2 倍甚至 4 倍)。
我尝试设置 InterpolationMode
和 SmoothingMode
,但似乎都没有对最终结果产生影响。
有办法解决这个问题吗?
public static Bitmap GenerateGradient(Color color1, Color color2, int width, int height, LinearGradientMode mode)
{
Bitmap bitmap = new(width, height);
using (Graphics graphics = Graphics.FromImage(bitmap))
using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, width, height), color1, color2, mode))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.FillRectangle(brush, new Rectangle(0, 0, width, height));
}
return bitmap;
}
编辑: 下面是我调用函数和保存位图的方法,在重新检查代码后我认为问题主要在于我如何生成颜色阴影。使用命名颜色代替生成的阴影后,结果更加平滑。
//Generates a random shade of the specified color
//by randomly adjusting the alpha value.
public static Color RandomShade(Color color)
{
var random = new Random(DateTime.Now.Millisecond);
int alpha = random.Next(0, 255);
return Color.FromArgb(alpha, color);
}
private void buttonGenerate_Click(object sender, EventArgs e)
{
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
Color color1 = RandomShade(Color.AliceBlue);
Color color2 = RandomShade(Color.Navy);
var bitmap = GenerateGradient(color1, color2, width, height, LinearGradientMode.ForwardDiagonal);
bitmap.Save("wallpaper.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
使用生成的阴影
使用命名颜色
问题出在 RandomShade()
方法上。通过使用 alpha 通道生成阴影,渐变也在对该通道进行插值。
我认为产生更好结果的方法是随机使用其他三个(颜色)通道使颜色变暗或变亮,并保持 alpha 不变。换句话说,只改变颜色的亮度。
例如:
public static Color RandomShadeV2(Color color)
{
const int Range = 1000;
const int Variance = 700;
var random = new Random(DateTime.Now.Millisecond);
int factor = random.Next(Range - Variance, Range + Variance + 1);
int r = color.R * factor / Range;
int g = color.G * factor / Range;
int b = color.B * factor / Range;
return Color.FromArgb(255, Math.Min(r, 255), Math.Min(g, 255), Math.Min(b, 255));
}
这将生成亮度系数介于原始颜色的 0.3 和 1.7 之间的阴影。
选择这些值作为亮度倍增器没有特别的原因。这些是我正在测试的。例如,如果您选择 0.0 到 2.0,您可能会经常获得非常暗或非常亮的阴影。 Range
和 Variance
常量是我用来推导亮度因子的:范围始终是整体(如 100%);方差是我允许它从那个点开始变化的,在这种情况下 700 代表 70%,所以最终的因素将在 100% - 70% = 30% = 0.3 和 100% + 70% = 170% = 1.7 之间.
我正在使用此函数生成一个简单的渐变位图,使用 LinearGradientBrush
我最后将其另存为文件以用作墙纸。但问题是结果看起来并不“平滑”,它看起来相当“断断续续”,因为你可以看到颜色的线条。
我使用屏幕边界作为位图的尺寸,增加尺寸并不能提高质量(我试过 2 倍甚至 4 倍)。
我尝试设置 InterpolationMode
和 SmoothingMode
,但似乎都没有对最终结果产生影响。
有办法解决这个问题吗?
public static Bitmap GenerateGradient(Color color1, Color color2, int width, int height, LinearGradientMode mode)
{
Bitmap bitmap = new(width, height);
using (Graphics graphics = Graphics.FromImage(bitmap))
using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, width, height), color1, color2, mode))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.FillRectangle(brush, new Rectangle(0, 0, width, height));
}
return bitmap;
}
编辑: 下面是我调用函数和保存位图的方法,在重新检查代码后我认为问题主要在于我如何生成颜色阴影。使用命名颜色代替生成的阴影后,结果更加平滑。
//Generates a random shade of the specified color
//by randomly adjusting the alpha value.
public static Color RandomShade(Color color)
{
var random = new Random(DateTime.Now.Millisecond);
int alpha = random.Next(0, 255);
return Color.FromArgb(alpha, color);
}
private void buttonGenerate_Click(object sender, EventArgs e)
{
int width = Screen.PrimaryScreen.Bounds.Width;
int height = Screen.PrimaryScreen.Bounds.Height;
Color color1 = RandomShade(Color.AliceBlue);
Color color2 = RandomShade(Color.Navy);
var bitmap = GenerateGradient(color1, color2, width, height, LinearGradientMode.ForwardDiagonal);
bitmap.Save("wallpaper.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
使用生成的阴影
使用命名颜色
问题出在 RandomShade()
方法上。通过使用 alpha 通道生成阴影,渐变也在对该通道进行插值。
我认为产生更好结果的方法是随机使用其他三个(颜色)通道使颜色变暗或变亮,并保持 alpha 不变。换句话说,只改变颜色的亮度。
例如:
public static Color RandomShadeV2(Color color)
{
const int Range = 1000;
const int Variance = 700;
var random = new Random(DateTime.Now.Millisecond);
int factor = random.Next(Range - Variance, Range + Variance + 1);
int r = color.R * factor / Range;
int g = color.G * factor / Range;
int b = color.B * factor / Range;
return Color.FromArgb(255, Math.Min(r, 255), Math.Min(g, 255), Math.Min(b, 255));
}
这将生成亮度系数介于原始颜色的 0.3 和 1.7 之间的阴影。
选择这些值作为亮度倍增器没有特别的原因。这些是我正在测试的。例如,如果您选择 0.0 到 2.0,您可能会经常获得非常暗或非常亮的阴影。 Range
和 Variance
常量是我用来推导亮度因子的:范围始终是整体(如 100%);方差是我允许它从那个点开始变化的,在这种情况下 700 代表 70%,所以最终的因素将在 100% - 70% = 30% = 0.3 和 100% + 70% = 170% = 1.7 之间.