GDI+ 的对角线阴影
Diagonal Shadow with GDI+
我正在尝试绘制对角线阴影。
首先我将所有像素设为黑色:
接下来用一个简单的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 中创建):
使用 Winforms 和 GDI+ 创建漂亮的阴影是一项相当艰巨的任务。
它既没有多边形缩放也没有模糊;让我们甚至不要考虑 3D..! - 但我们至少可以在不做太多工作的情况下做一些事情,并为许多图像获得不错的结果..
假设您已经有一张从背景中裁剪下来的图像。
下一步是将所有颜色变成黑色。
那么我们很可能想要添加一定程度的透明度,这样阴影落在的背景仍然会发光。
通过使用合适的 ColorMatrix
.
这两项任务都非常有效地完成了
对于非常透明的版本,我们还可以通过使用偏移绘制图像来创建简单的模糊效果。为了获得最佳效果,我会使用 3 个不同的 weights/alpha 值将其绘制九次..
高质量模糊是一门艺术,您甚至可以通过 Adobe Photoshop 或 Affinity Photo[= 等专业软件中的滤镜和调整来了解这一点94=]。这是一组 nice 有趣的链接..
但是由于我们只处理 b/w 位图,所以简单的方法就足够了。我使用 5%、10% 和 20% 的 3 个 alpha 值用于第 4 个角、第 4 个边和1 个中心图纸。
最后一步是绘制带有一些 倾斜 的阴影。
这是解释here;但是,虽然这看起来很简单,但也有些不切实际。 DrawImage
overlay 期望的三个点需要计算。
所以这里有一个方法可以做到这一点;请注意,这是一种高度简化的方法:
叠加取三点,即6浮点数。我们只使用 3 个数字:
- 一个是偏斜量;
0.5
表示顶部向右移动位图宽度的一半。
- 另外两个是生成的边界框的缩放比例。
1
和0.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)
仔细看可以看到左脚的影子在脚下一点点。这是因为双脚不在同一水平面上,并且由于垂直压缩,基线会分开。要纠正这个问题,我们要么修改图像,要么添加一个微小的旋转。
看你的例子很明显,你需要把它拆开,分开对待'house'和'tree'!
签名保持简单;这始终是易用性和编码工作量之间的平衡。可能希望有一个参数 take angle 来控制倾斜。随意进行必要的计算..
请注意,在其他按钮后面添加功能将超出问题的范围。我只想说大多数只是一条线来做图,十几条线来设置颜色矩阵..
这是 'Skew' 按钮中的代码:
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
..
我正在尝试绘制对角线阴影。
首先我将所有像素设为黑色:
接下来用一个简单的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 中创建):
使用 Winforms 和 GDI+ 创建漂亮的阴影是一项相当艰巨的任务。
它既没有多边形缩放也没有模糊;让我们甚至不要考虑 3D..! - 但我们至少可以在不做太多工作的情况下做一些事情,并为许多图像获得不错的结果..
假设您已经有一张从背景中裁剪下来的图像。
下一步是将所有颜色变成黑色。
那么我们很可能想要添加一定程度的透明度,这样阴影落在的背景仍然会发光。
通过使用合适的 ColorMatrix
.
对于非常透明的版本,我们还可以通过使用偏移绘制图像来创建简单的模糊效果。为了获得最佳效果,我会使用 3 个不同的 weights/alpha 值将其绘制九次..
高质量模糊是一门艺术,您甚至可以通过 Adobe Photoshop 或 Affinity Photo[= 等专业软件中的滤镜和调整来了解这一点94=]。这是一组 nice 有趣的链接..
但是由于我们只处理 b/w 位图,所以简单的方法就足够了。我使用 5%、10% 和 20% 的 3 个 alpha 值用于第 4 个角、第 4 个边和1 个中心图纸。
最后一步是绘制带有一些 倾斜 的阴影。
这是解释here;但是,虽然这看起来很简单,但也有些不切实际。 DrawImage
overlay 期望的三个点需要计算。
所以这里有一个方法可以做到这一点;请注意,这是一种高度简化的方法:
叠加取三点,即6浮点数。我们只使用 3 个数字:
- 一个是偏斜量;
0.5
表示顶部向右移动位图宽度的一半。 - 另外两个是生成的边界框的缩放比例。
1
和0.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)
仔细看可以看到左脚的影子在脚下一点点。这是因为双脚不在同一水平面上,并且由于垂直压缩,基线会分开。要纠正这个问题,我们要么修改图像,要么添加一个微小的旋转。
看你的例子很明显,你需要把它拆开,分开对待'house'和'tree'!
签名保持简单;这始终是易用性和编码工作量之间的平衡。可能希望有一个参数 take angle 来控制倾斜。随意进行必要的计算..
请注意,在其他按钮后面添加功能将超出问题的范围。我只想说大多数只是一条线来做图,十几条线来设置颜色矩阵..
这是 'Skew' 按钮中的代码:
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
..