public void PaintVignette(Graphics g, Rectangle bounds)
{
Rectangle ellipsebounds = bounds;
ellipsebounds.Offset(-ellipsebounds.X, -ellipsebounds.Y);
int x = ellipsebounds.Width - (int)Math.Round(.70712 * ellipsebounds.Width);
int y = ellipsebounds.Height - (int)Math.Round(.70712 * ellipsebounds.Height);
ellipsebounds.Inflate(x, y);
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(ellipsebounds);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
brush.WrapMode = WrapMode.Tile;
brush.CenterColor = Color.FromArgb(0, 0, 0, 0);
brush.SurroundColors = new Color[] { Color.FromArgb(255, 0, 0, 0) };
Blend blend = new Blend();
blend.Positions = new float[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F };
blend.Factors = new float[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f };
brush.Blend = blend;
Region oldClip = g.Clip;
g.Clip = new Region(bounds);
g.FillRectangle(brush, ellipsebounds);
g.Clip = oldClip;
}
}
}
public Bitmap Vignette(Bitmap b)
{
Bitmap final = new Bitmap(b);
using (Graphics g = Graphics.FromImage(final)) {
PaintVignette(g, new Rectangle(0, 0, final.Width, final.Height));
return final;
}
}
What's going on here? First I wrote code that would fill a rectangle with an elliptical gradient brush that went from white to black. Then I modified the code so that the filled area would also include the corners. I did this by increasing the rectangle size by the difference between the rectangle dimensions and sqrt(2)/2 * the rectangle dimensions.
Why sqrt(2)/2? Because the point (sqrt(2)/2, sqrt(2)/2) is the 45 degree angle point on a unit circle. Scaling by the width and height gives the distance needed to inflate the rect to make sure it's fully covered.
Then I adjusted the Blend of the gradient to be much more white in the center.
Then I changed the color from white to pure transparent black and from black to pure opaque black. This has the effect of painting the far corners black and shade less on the way in to the center.
Finally, I wrote a utility method that runs on a Bitmap (I haven't tested this part - I tested the code on a graphics from a Panel, but I think it will work here too.
If your picture is in a file, and if that is fast enough for your requirements, you can use the command line tool convert of ImageMagick, it has an option -vignette. To call this from within a C# program, you can run it via System.Diagnostics.Process.Start, or you use this .NET wrapper for ImageMagick.
发布评论
评论(2)
我相信这会满足您的要求:
这里发生了什么?首先,我编写了用从白色到黑色的椭圆渐变画笔填充矩形的代码。然后我修改了代码,以便填充区域也包括角点。我通过增加矩形尺寸与 sqrt(2)/2 * 矩形尺寸之间的差值来实现此目的。
为什么要开方(2)/2?因为点(sqrt(2)/2, sqrt(2)/2)是单位圆上的45度角点。按宽度和高度缩放给出了膨胀矩形以确保其被完全覆盖所需的距离。
然后我调整渐变的混合,使其中心更加白色。
然后我将颜色从白色更改为纯透明黑色,从黑色更改为纯不透明黑色。这具有将远角涂成黑色并且在到达中心的过程中阴影较少的效果。
最后,我编写了一个在位图上运行的实用程序方法(我还没有测试这部分 - 我在面板上的图形上测试了代码,但我认为它在这里也可以工作。
I believe this will do what you want:
What's going on here? First I wrote code that would fill a rectangle with an elliptical gradient brush that went from white to black. Then I modified the code so that the filled area would also include the corners. I did this by increasing the rectangle size by the difference between the rectangle dimensions and sqrt(2)/2 * the rectangle dimensions.
Why sqrt(2)/2? Because the point (sqrt(2)/2, sqrt(2)/2) is the 45 degree angle point on a unit circle. Scaling by the width and height gives the distance needed to inflate the rect to make sure it's fully covered.
Then I adjusted the Blend of the gradient to be much more white in the center.
Then I changed the color from white to pure transparent black and from black to pure opaque black. This has the effect of painting the far corners black and shade less on the way in to the center.
Finally, I wrote a utility method that runs on a Bitmap (I haven't tested this part - I tested the code on a graphics from a Panel, but I think it will work here too.
如果您的图片位于文件中,并且速度足以满足您的要求,则可以使用 convert rel="nofollow noreferrer">ImageMagick,它有一个选项
-vignette
。要从 C# 程序中调用它,您可以通过 System.Diagnostics.Process.Start 运行它,或者使用 this 。 NET 包装器 ImageMagick。If your picture is in a file, and if that is fast enough for your requirements, you can use the command line tool
convert
of ImageMagick, it has an option-vignette
. To call this from within a C# program, you can run it via System.Diagnostics.Process.Start, or you use this .NET wrapper for ImageMagick.