【问题标题】:How do I draw a Drop Shadow at any Location on a Form?如何在表单的任何位置绘制投影?
【发布时间】:2014-09-09 08:45:32
【问题描述】:

使用 GDI+,如何在指定坐标处绘制边框阴影或投影?我不想将阴影附加到任何东西上,我只需要从 x40,0px 到 x140px,0px 绘制一个阴影。我无法找到有关此的任何信息,并且我开始认为这是不可能的。

我的意图是在控件底部的某个位置绘制阴影,但我不希望它是控件的整个宽度,这就是为什么我专门询问仅在指定位置绘制的原因。

【问题讨论】:

  • 我很想知道为什么您希望在您的 winform 上看似“随机”地放置阴影?你想达到什么效果?
  • 完全控制它的绘制位置。 only 解决方案我已经能够找到从左下角一直到控件右下角的阴影。我需要更多地控制阴影的开始位置和结束位置。 “解决不同问题”的现有解决方案不允许对阴影的起点和终点进行任何进一步控制。
  • 你现在怎么画阴影,有什么问题?影子不是要控制的东西。你想要动画阴影还是什么?在图形中,阴影是昂贵的。因此,大多数解决方案都针对实时操作(假阴影)进行了优化。用物理的话来说,你也不能直接控制阴影,你可以控制物体、灯光、距离等,阴影是基于这些产生的。您对阴影的定义有点令人困惑:从 x40,0px 到 x140px,0px 的阴影。谁丢了?你能创建一个草图或屏幕截图来直观地描述问题吗?
  • 创建阴影的 png 图像,然后在您想要的位置绘制该图像的一部分

标签: c# .net winforms drawing gdi+


【解决方案1】:

这是一段可以帮助您入门的代码。

drawShadow 方法沿GraphicsPath 绘制具有给定颜色和深度的阴影。

使用GraphicsPath 可以让您绘制比Rectangles 更复杂形状的阴影。

阴影是用一个颜色矢量绘制的,该矢量逐渐从阴影到背景颜色并向右和向下移动。 (可以通过改变阴影向量来改变方向。值大于1需要更大的Pen宽度!(*))

为了演示例程,我添加了一个getRectPath 函数,该函数从Rectangle 创建一个GraphicsPath 和一个调用绘图例程的按钮单击。

当然,在生产代码中,您必须将其附加到 Paint 事件!

void drawShadow(Graphics G, Color c, GraphicsPath GP, int d)
{
    Color[] colors = getColorVector(c, this.BackColor, d).ToArray();
    for (int i = 0; i < d; i++)
    {
        G.TranslateTransform(1f, 0.75f);                // <== shadow vector!
        using (Pen pen = new Pen(colors[i], 1.75f  ) )  // <== pen width (*)
            G.DrawPath(pen, GP);
    }
    G.ResetTransform();
}


List<Color> getColorVector(Color fc, Color bc, int depth)
{
    List<Color> cv = new List<Color>();
    float dRed = 1f * (bc.R - fc.R) / depth;
    float dGreen = 1f * (bc.G - fc.G) / depth;
    float dBlue = 1f * (bc.B - fc.B) / depth;
    for (int d = 1; d <= depth; d++)
         cv.Add(Color.FromArgb(255,   (int) (fc.R + dRed * d),
           (int) (fc.G + dGreen * d), (int) (fc.B + dBlue * d) ));
    return cv;
}

GraphicsPath getRectPath(Rectangle R)
{
    byte[] fm = new byte[3];
    for (int b = 0; b < 3; b++) fm[b] = 1;
    List<Point> points = new List<Point>();
    points.Add(new Point(R.Left, R.Bottom));
    points.Add(new Point(R.Right, R.Bottom));
    points.Add(new Point(R.Right, R.Top));
    return new GraphicsPath(points.ToArray(), fm);
}

private void button1_Click(object sender, EventArgs e)
{
    using (Graphics G = this.CreateGraphics())
      drawShadow(G, Color.Black, getRectPath(new Rectangle(111, 111, 222, 222)), 17);
}

编辑:我已经更改了解决方案,以允许复杂的阴影和任意阴影矢量,而不会出现 Alpha 通道的重叠造成难看的伪影。这假设背景具有统一的颜色!

【讨论】:

    猜你喜欢
    • 2015-07-27
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多