【问题标题】:Diagonal Shadow with GDI+使用 GDI+ 的对角阴影
【发布时间】:2017-02-18 12:09:54
【问题描述】:

我正在尝试绘制对角线阴影。

首先我将所有像素都设为黑色:

接下来用一个简单的for cicle就是结果

现在我想对角拉伸这张图片来模拟阴影。
我试过了:

Bitmap b = new Bitmap(tImage.Width + 100, tImage.Height);
Graphics p = Graphics.FromImage(b);
p.RotateTransform(30f);
p.TranslateTransform(100f, -200f);
p.DrawImage(tImage, new Rectangle(0, -20, b.Width+20, b.Height));

但图像被旋转和平移。

请问有人可以帮我解决吗?

我需要它看起来像这样(在 Photoshop 中创建):

【问题讨论】:

  • 您尝试了吗skewing? - 请注意,这仍然是严格的 2d!
  • 哦,不,这对我来说是新的。我试试
  • 我试过了,但我看到图像翻转或非常小。一个例子?

标签: c# gdi shadow


【解决方案1】:

使用 Winforms 和 GDI+ 创建漂亮的阴影是一项艰巨的任务。

它既没有多边形缩放也没有模糊;让我们甚至不考虑3D ..! - 但是我们至少可以在不做太多工作的情况下做一些事情,并为许多图像获得不错的结果..

假设您已经有一张从背景中剪下的图片。

下一步是将所有颜色变为黑色。

那么我们很可能想要添加某种程度的透明度,以便阴影落在背景上,仍然可以透过。

通过使用合适的ColorMatrix,这两项任务都非常有效地完成。

使用非常透明的版本,我们还可以通过绘制带有偏移的图像来创建简单的模糊。为了获得最佳效果,我会用 3 个不同的权重/alpha 值绘制九次。

高质量的模糊是一门艺术,您只需查看专业软件(如 Adobe PhotoshopAffinity Photo)中的滤镜和调整即可。这是nice 一组有趣的链接..

但由于我们只处理黑白位图,因此简单的方法就足够了。我使用 3 个 5%、10% 和 20% 的 alpha 值用于 4 个角、4 个边缘和 1 个中心绘图。

最后一步是绘制带有一些倾斜的阴影。

这是解释here;但是,虽然这看起来很简单,但也有些不切实际。需要计算DrawImage 叠加层期望的三个点。

所以这里有一个方法可以做到这一点;请注意,这是一种高度简化的方法:

叠加层需要三个点,即 6 个浮点数。我们只使用 3 个数字:

  • 一个为倾斜量; 0.5 表示顶部向右移动位图宽度的一半。
  • 另外两个是生成的边界框的缩放比例。 10.5 表示宽度不变,高度降低为50%

函数如下:

public Bitmap SkewBitmap(Bitmap inMap, float skewX, float ratioX, float ratioY )
{
    int nWidth = (int)(inMap.Width * (skewX + ratioX));
    int nHeight = (int)(Math.Max(inMap.Height, inMap.Height * ratioY));
    int yOffset = inMap.Height - nHeight;

    Bitmap outMap = new Bitmap(nWidth, nHeight);

    Point[] destinationPoints = {
        new Point((int)(inMap.Width * skewX), (int)(inMap.Height * ratioY) + yOffset),
        new Point((int)(inMap.Width * skewX + inMap.Width * ratioX),
                  (int)(inMap.Height * ratioY) + yOffset),
        new Point(0, inMap.Height + yOffset ) };

        using (Graphics g = Graphics.FromImage(outMap))
        g.DrawImage(inMap, destinationPoints);

    return outMap;
}

注意一些简化:

  • 如果您想将阴影放在左边,您不仅需要将前两个点向左移动,还需要调整宽度的计算以及将对象覆盖在阴影上的方式.

  • 如果您研究 MSDN 示例,您会发现 DrawImage 覆盖还允许进行旋转。我没有将它添加到我们的函数中,因为计算起来要复杂得多,甚至只是写一个签名。

  • 如果你想知道这六个数字的信息在哪里,这里是完整的布局:

    • 3 进入我们的参数
    • 1 是我们不做的旋转角度
    • 2 可以是旋转中心点,也可以是转换结果的点 (deltaX&Y)
  • 如果您仔细观察,您会发现左脚的阴影略低于脚。这是因为脚不在同一水平线上,并且随着垂直压缩,基线会分开。为了纠正这一点,我们要么修改图像,要么添加一个微小的旋转。

  • 看看你的例子,很明显你需要把它拆开,分别处理“房子”和“树”!

  • 签名保持简单;这始终是易用性和编码工作量之间的平衡。 On 可能需要一个参数来控制倾斜。随意进行必要的计算..

请注意,在其他按钮后面添加功能将超出问题的范围。可以这么说,大多数只需要一条线来绘制,十几条线来设置颜色矩阵..

这是“倾斜”按钮中的代码:

Bitmap bmp = SkewBitmap((Bitmap)pictureBox4.Image, 0.5f, 1f, 0.5f);

pictureBox5.Image = pictureBox1.Image;
pictureBox5.BackgroundImage = bmp;
pictureBox5.ClientSize = new Size(bmp.Width, bmp.Height);

我没有在阴影上绘制对象,而是使用了PictureBox 的额外层。你当然会结合这两个Bitmaps..

【讨论】:

  • 坦克拖!你太棒了。坦克为您提供帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 2014-09-15
  • 2016-10-05
  • 2016-02-20
  • 2011-09-10
相关资源
最近更新 更多