首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >绘制渐变矩形的一种有效方法

绘制渐变矩形的一种有效方法
EN

Stack Overflow用户
提问于 2013-02-26 02:35:31
回答 2查看 1.3K关注 0票数 6

我正在生成一堆具有不同大小和位置的RectangleF对象。在GDI+中用渐变笔刷填充它们的最好方法是什么?

在WPF中,我可以创建一个LinearGradientBrush,设置开始和结束relative点,WPF会处理剩下的事情。

然而,在GDI+中,渐变笔刷构造函数需要绝对坐标的位置,这意味着我必须为每个矩形创建一个笔刷,这将是一个非常复杂的操作。

我是不是错过了什么,或者这确实是唯一的方法?

EN

回答 2

Stack Overflow用户

发布于 2013-02-26 04:29:13

如果您只想声明画笔一次,则可以在应用渐变之前指定变换。请注意,使用转换将覆盖许多可以在LinearGradientBrush上指定的构造函数参数。

LinearGradientBrush.Transform Property (System.Drawing.Drawing2D)

若要修改转换,请调用笔刷对象上与所需矩阵操作相对应的方法。请注意,矩阵运算是不可交换的,因此顺序很重要。出于您的目的,您可能希望在每次呈现矩形时按以下顺序进行操作:缩放、旋转、偏移/平移。

LinearGradientBrush.ResetTransform Method @ MSDN

LinearGradientBrush.ScaleTransform Method (Single, Single, MatrixOrder) @ MSDN

LinearGradientBrush.RotateTransform Method (Single, MatrixOrder) @ MSDN

LinearGradientBrush.TranslateTransform Method (Single, Single, MatrixOrder) @ MSDN

请注意,系统级绘制工具实际上并不包含渐变画笔的常规定义,因此如果您对创建多个画笔的性能有顾虑,创建大量渐变画笔的成本不应超过GDI+/System.Drawing维护定义渐变和样式所需的数据。您可以根据需要创建每个矩形的笔刷,而不必深入研究通过transform自定义笔刷所需的数学运算。

Brush Functions (Windows) @ MSDN

这是一个可以在WinForms应用程序中测试的代码示例。这个应用程序使用渐变笔刷绘制瓷砖,使用45度渐变,缩放到瓷砖的最大尺寸(天真计算)。如果您摆弄这些值和转换,您可能会发现,如果您有非平凡的渐变定义,则不值得使用为所有矩形设置转换的技术。否则,请记住,您的变换是在世界级别应用的,在GDI世界中,y轴是颠倒的,而在笛卡尔数学世界中,它是从下到上排序的。这也会导致角度按顺时针方向应用,而在三角中,角度按逆时针方向递增y轴向上的值。

代码语言:javascript
运行
复制
using System.Drawing.Drawing2D;

namespace TestMapTransform
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Rectangle rBrush = new Rectangle(0,0,1,1);
            Color startColor = Color.DarkRed;
            Color endColor = Color.White;
            LinearGradientBrush br = new LinearGradientBrush(rBrush, startColor, endColor, LinearGradientMode.Horizontal);

            int wPartitions = 5;
            int hPartitions = 5;

            int w = this.ClientSize.Width;
            w = w - (w % wPartitions) + wPartitions;
            int h = this.ClientSize.Height;
            h = h - (h % hPartitions) + hPartitions;

            for (int hStep = 0; hStep < hPartitions; hStep++)
            {
                int hUnit = h / hPartitions;
                for (int wStep = 0; wStep < wPartitions; wStep++)
                {
                    int wUnit = w / wPartitions;

                    Rectangle rTile = new Rectangle(wUnit * wStep, hUnit * hStep, wUnit, hUnit);

                    if (e.ClipRectangle.IntersectsWith(rTile))
                    {
                        int maxUnit = wUnit > hUnit ? wUnit : hUnit;

                        br.ResetTransform();
                        br.ScaleTransform((float)maxUnit * (float)Math.Sqrt(2d), (float)maxUnit * (float)Math.Sqrt(2d), MatrixOrder.Append);
                        br.RotateTransform(45f, MatrixOrder.Append);
                        br.TranslateTransform(wUnit * wStep, hUnit * hStep, MatrixOrder.Append);

                        e.Graphics.FillRectangle(br, rTile);

                        br.ResetTransform();
                    }
                }
            }
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            this.Invalidate();
        }
    }
}

以下是输出的快照:

票数 1
EN

Stack Overflow用户

发布于 2013-02-26 02:59:45

我建议您创建一个泛型方法,如下所示:

代码语言:javascript
运行
复制
public void Paint_rectangle(object sender, PaintEventArgs e)
    {
        RectangleF r = new RectangleF(0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
        if (r.Width > 0 && r.Height > 0)
        {
            Color c1 = Color.LightBlue;
            Color c2 = Color.White;
            Color c3 = Color.LightBlue;

            LinearGradientBrush br = new LinearGradientBrush(r, c1, c3, 90, true);
            ColorBlend cb = new ColorBlend();
            cb.Positions = new[] { 0, (float)0.5, 1 };
            cb.Colors = new[] { c1, c2, c3 };
            br.InterpolationColors = cb;

            // paint
            e.Graphics.FillRectangle(br, r);
        }
    }

然后,对每个矩形调用:

代码语言:javascript
运行
复制
yourrectangleF.Paint += new PaintEventHandler(Paint_rectangle);

如果渐变颜色都相同,则可以使该方法更短。希望这会有帮助..。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15073939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档