我想知道如何使用C#和.NET在图片上创建vignetting effect。
有没有人有任何想法如何做到这一点?或者是否有任何资源可以为我完成算法?
答案 0 :(得分:10)
我相信这会做你想要的:
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;
}
}
这里发生了什么?首先,我编写了一个代码,用一个椭圆形渐变画笔填充一个矩形,从白色到黑色。然后我修改了代码,以便填充区域也包括角落。我这样做是通过增加矩形大小乘以矩形尺寸和sqrt(2)/ 2 *矩形尺寸之间的差异。
为什么sqrt(2)/ 2?因为点(sqrt(2)/ 2,sqrt(2)/ 2)是单位圆上的45度角点。按宽度和高度缩放给出了使矩形膨胀所需的距离,以确保它完全被覆盖。
然后我调整渐变的混合在中心变得更白。
然后我将颜色从白色变为纯透明黑色,从黑色变为纯不透明黑色。这样可以在通往中心的途中将远角涂成黑色和阴影。
最后,我写了一个在Bitmap上运行的实用程序方法(我没有测试过这个部分 - 我在Panel上测试了代码,但我认为它也适用于此。
答案 1 :(得分:2)
如果您的图片位于文件中,并且该图片足够快以满足您的要求,则可以使用ImageMagick的命令行工具convert
,它有一个选项-vignette
。要在C#程序中调用它,可以通过System.Diagnostics.Process.Start运行它,或者对ImageMagick使用this .NET wrapper。