用三种颜色的渐变填充面板

2024-04-21

我正在做一个项目,我必须使用 C# 做一种颜色选择器。

所以我决定在 Win Forms 应用程序中建立一个具有此背景的面板。

背景应具有 RGB 三种颜色的渐变:红色 (0 - 255)、蓝色 (0 - 255) 和绿色 = 0。

但我找不到任何关于我应该为此使用什么的信息。

我尝试编写一些代码,这就是我所做的。

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



    private void Form1_Load(object sender, EventArgs e)
    {
        panel1.Paint += new PaintEventHandler(panel1_Paint);
        panel1.Refresh();
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        Point startPoint = new Point(0, 0);
        Point endPoint = new Point(150, 150);

        LinearGradientBrush lgb =
            new LinearGradientBrush(startPoint, endPoint,     Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 255, 255, 0));
        Graphics g = e.Graphics;
        g.FillRectangle(lgb, 0, 0, 150, 150);
       // g.DrawLine(new Pen(Color.Yellow, 1.5f), startPoint, endPoint);
    }
}

}

现在我有了这个渐变的面板

我应该用什么来获得第一张图片的渐变?

第二个问题:点击这个背景后我应该怎么做才能获得像素颜色?


这是使用多色的示例LinearGradientBrush in the Paint event:

LinearGradientBrush linearGradientBrush =
   new LinearGradientBrush(panel4.ClientRectangle, Color.Red, Color.Yellow, 45);

ColorBlend cblend = new ColorBlend(3);
cblend.Colors = new Color[3]  { Color.Red, Color.Yellow, Color.Green };
cblend.Positions = new float[3] { 0f, 0.5f, 1f };

linearGradientBrush.InterpolationColors = cblend;

e.Graphics.FillRectangle(linearGradientBrush, panel4.ClientRectangle);

您可以自由改变颜色数量、停止点的角度或分布。只需确保始终具有相同数量的颜色和停止点,并让它们从 0 开始并以 1 结束。

构造函数中的颜色被忽略,顺便说一句..

要获得单击的颜色,您可以编码MouseClick:

Color clickedColor = Color.Empty;

private void panel_MouseClick(object sender, MouseEventArgs e)
{
    using (Bitmap bmp = new Bitmap( panel.ClientSize.Width, panel4.ClientSize.Height))
    {
        panel.DrawToBitmap(bmp,panel.ClientRectangle);
        clickedColor = bmp.GetPixel(e.X, e.Y);
    }
}

如果您想获得大量点击,最好保留Bitmap在类级别变量中,而不是一直重新创建它。将其设置为面板的背景图像,正如卡拉的答案所假设的那样也可能是一个不错的选择。

这应该可以回答标题中的问题。但是,您的第一张图像不显示三种颜色的渐变。它显示了四种颜色的二维渐变。对于这种更昂贵的着色方法,您应该将颜色放在Bitmap并将其设置为Panel's BackgroundImage..

Update1这是一段创建 2D 渐变的代码:

Bitmap Gradient2D(Rectangle r, Color c1, Color c2, Color c3, Color c4)
{
    Bitmap bmp = new Bitmap(r.Width, r.Height);

    float delta12R = 1f * (c2.R - c1.R) / r.Height;
    float delta12G = 1f * (c2.G - c1.G) / r.Height;
    float delta12B = 1f * (c2.B - c1.B) / r.Height;
    float delta34R = 1f * (c4.R - c3.R) / r.Height;
    float delta34G = 1f * (c4.G - c3.G) / r.Height;
    float delta34B = 1f * (c4.B - c3.B) / r.Height;
    using (Graphics G = Graphics.FromImage(bmp) )
    for (int y = 0; y < r.Height; y++)
    {
        Color c12 = Color.FromArgb(255,  c1.R + (int)(y * delta12R), 
              c1.G + (int)(y * delta12G), c1.B + (int)(y * delta12B));
        Color c34 = Color.FromArgb(255, c3.R + (int)(y * delta34R), 
              c3.G + (int)(y * delta34G), c3.B + (int)(y * delta34B));
        using ( LinearGradientBrush lgBrush = new LinearGradientBrush(
              new Rectangle(0,y,r.Width,1), c12, c34, 0f) )
        {  G.FillRectangle(lgBrush, 0, y, r.Width, 1);  }
    }
    return bmp;
}

以下是使用方法:

    public Form1()
    {
        InitializeComponent();
        panel.BackgroundImage = Gradient2D(panel.ClientRectangle, 
               Color.Black, Color.FromArgb(255, 0, 255, 0), Color.Red, Color.Yellow);
    }

这使用简单LinearGradientBrushes没有额外的颜色列表低于高度Panel.

注意Color.Green是相当暗的色调,所以我用了FromRgb以获得更亮的绿色。如果你的Panel大于 256 像素,您可能需要通过填充大条纹来优化;如果它是垂直的,您可能需要更改循环以遍历 x 而不是 y..

结果如下:

现在只需单击一下即可选择颜色BackgroundImage:

private void panel_MouseClick(object sender, MouseEventArgs e)
{
    clickedColor = ((Bitmap)panel.BackgroundImage).GetPixel(e.X, e.Y);
}

更新2:

当看过去时这个 MSDN 页面 https://learn.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-create-a-path-gradient我们可以发现实际上有一个内置工具可以创建 2D 渐变。

它是路径渐变画笔 https://learn.microsoft.com/en-us/dotnet/api/system.drawing.drawing2d.pathgradientbrush?view=netframework-4.7.2

这是一个例子..:

..和代码:

Bitmap Gradient2D(Rectangle r, Color c1, Color c2, Color c3, Color c4)
{
    List<Color> colors = new List<Color> {  c1, c3, c4, c2 };
    Bitmap bmp = new Bitmap(r.Width, r.Height);
    using (Graphics g = Graphics.FromImage(bmp))
    for (int y = 0; y < r.Height; y++)
    {

        using (PathGradientBrush pgb = new PathGradientBrush(getCorners(r).ToArray()))
        {
            pgb.CenterColor = medianColor(colors);
            pgb.SurroundColors = colors.ToArray();
            g.FillRectangle(pgb, 0, y, r.Width, 1);
        }
    }
    return bmp;
}

这使用两个简单的辅助函数。返回矩形的角点:

public List<PointF> getCorners(RectangleF r)
{
    return new List<PointF>() { r.Location, new PointF(r.Right, r.Top),
        new PointF(r.Right, r.Bottom), new PointF(r.Left, r.Bottom)};
}

另一个计算中值颜色List<Color>。这用作CenterColor..:

public static Color medianColor(List<Color> cols)
{
    int c = cols.Count;
    return Color.FromArgb(cols.Sum(x => x.A) / c, cols.Sum(x => x.R) / c,
        cols.Sum(x => x.G) / c, cols.Sum(x => x.B) / c);
}

结果与使用条纹的结果几乎相同LinearGradientBrushes。它更简单并且性能应该更好一些;这显然是我推荐的..

请注意改变顺序颜色(或角)!这SurroundColors适用于矩形的对角..

Note:

当研究这一页时,人们会发现实际上有four该刷子的不同用途。

它们的设置方式不同(GraphicsPath or Point[]),要填充哪些颜色集合(SurroundColors or InterpolationColors.Colors)以及如何调用它(使用形状或路径)。而且结果也相差很大。

另请注意,仅three显示了四种方法的结果,尽管提供了所有四种方法的代码!..

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用三种颜色的渐变填充面板 的相关文章

  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 为什么这个没有特殊字符的正则表达式会匹配更长的字符串?

    我正在使用此方法来尝试查找匹配项 例如 Regex Match A2 TS OIL TS OIL RegexOptions IgnoreCase Success 我得到了真实的结果 我很困惑 我认为这应该返回 false 因为模式中没有特殊
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 是否有相当于 Clang/LLVM 的 .spec 文件,在哪里可以找到参考?

    The gcc驱动程序可以配置为使用特定的链接器 特定的选项和其他细节 例如覆盖系统头 specs files 当前 截至撰写本文时 GCC 版本 4 9 0 的手册此处描述了规范文件 https gcc gnu org onlinedoc
  • 在 EnvDTE 中调试时捕获 VS 局部变量

    是否可以使用 EnvDTE 进行 vsix Visual Studio 扩展来捕获本地和调试窗口使用的调试数据 或者可以通过其他方法吗 我想创建一个自定义的本地窗口 我们可以修改它以根据需要显示一些较重的内容 而无需为高级用户牺牲原始的本地
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 简单的颜色变化

    我正在创建一个用户界面 用户可以在其中更改页面的颜色值 我想要的是获取分配给其背景颜色的值并将其变亮一定程度 我只是想获得一条亮点线 而不必每次都制作新图像 示例 用户将背景颜色设置为 ECECEC 现在我希望某个元素边框变成 F4F4F4
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用

随机推荐

  • 从android执行.bat文件

    我正在尝试执行 xxx bat 文件以从我的 Android 应用程序重命名该文件 听到的是我的代码 Runtime getRuntime exec Environment getExternalStorageDirectory File
  • 如何衡量服务器的请求和响应时间?

    我正在使用 asynctask 和 json 解析来从服务器获取响应 我如何测量请求和响应时间 以下是我的网络服务代码 任何人都可以帮助我吗 public class JSONParser static InputStream is nul
  • 为什么我的 redux 状态没有更新

    状态未更新 当调度操作时 状态应更新为 isAuthenticated 为 true 但状态未更新 redux 返回初始状态而不是更新后的状态 export function setCurrentUser user console log
  • 有什么好的 JavaScript 货币或小数类吗?

    我正在尝试处理 JavaScript 值 例如23 45 但我希望能够对这些值进行数学运算 加法 减法 乘法 除法 而不会遇到浮点问题 是的 有时我可能需要对结果进行四舍五入 但我希望它给出合理的答案 在 JavaScript 中考虑一下
  • 发送的邮件项目无效使用

    背景 The 在这里提问 https stackoverflow com questions 38405423 outlook send event class 38407819 38407819提供了进一步的解释 在这种情况下 我想知道为
  • Angular2 Ng2文件上传CORS问题

    我是新来尝试angular2 我已经安装了 angular2 文件上传 我复制了教程中的所有代码here http valor software com ng2 file upload 我完全复制了开发人员在那里写的内容 但我遇到这样的问题
  • 有没有办法使用 flutter ping 本地 IP 地址?

    我想检查特定设备是否连接到我的网络 我有该设备的 IP 地址 我无法找到使用 flutter 应用程序 ping 该设备的方法 这里的目标是通过 ping 设备来检查特定设备是否连接到本地网络 你能帮我吗 用这个 import dart i
  • 源注释.h ? C++ [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions Visua
  • 在SPARQL中使用LIMIT时如何获取结果总数?

    我有一个 SPARQL 查询 它返回结果LIMIT共 20 个 在此查询中 我还想知道结果总数 而无需运行查询两次 一次运行LIMIT和一个没有LIMIT 例如 运行查询时 可能的结果总数为 500 个 其中LIMIT它一次只显示 20 个
  • 如何发送元数据 HTTP POST 请求

    假设我想发送这些类型的请求 其中 json 数据中有 meta 我该如何处理 我把它作为 json 数据 amount 500 narration Test Int l bank transfers currency USD benefic
  • 如何启动一个新的大型 ZF2 项目?

    我将使用 ZF2 创建一个新项目 事实上 我必须升级 ZF1 项目 但我决定从头开始 我的项目非常庞大 已经被来自世界各地的志愿者翻译成 10 种不同的语言 我遇到的困难是分析 ZF2 告诉我要遵循的模块结构 该软件允许 ISP 领域的中小
  • 如何使用 Selenium 找到文本位置?

    我正在尝试使用 Selenium 查找网页上某些文本的位置 我可以使用 isTextPresent 函数来告诉我文本是否出现 但随后我想知道它实际在哪里 更广泛的问题是我想单击此文本 问题是我似乎无法单击此文本 我认为该文本位于页面上嵌入的
  • sqlalchemy中查询相关表

    所以我有两个表 员工 和 详细信息 如下所示 class Employee Base tablename employees id Column Integer Sequence employee id seq primary key Tr
  • 如何在 ASP.NET 5 中使用基于 IAppBuilder 的 Owin 中间件

    ASP NET 5 ASP NET vNext 与 Katana 一样基于 OWIN 但具有不同的抽象 尤其IAppBuilder已被替换为IApplicationBuilder 许多中间件库依赖于IAppBuilder并且尚未更新以支持
  • 使用多个条件查找所有结果

    我有一个包含多列的表 我想使用条件过滤表并接收包含匹配项的范围 1 我知道我可以使用循环轻松地在表中进行迭代 或者 2 我可以在列中添加过滤器 我不喜欢 1 因为表中的迭代太慢 但我可以做到这一点 Excel 是否有一种函数可以一步返回按特
  • BigQuery更新如何获取更新的行数

    我正在使用 Google Cloud Functions 连接到 Google Bigquery 数据库并更新一些行 云函数是使用Python 3编写的 当我通过函数运行更新 dml 时 我需要帮助弄清楚如何获取结果消息或更新 更改的行数
  • dplyr 0.3 无法inner_join data.table?

    我有以下设置并加载了 dplyr 0 3 和 data table 1 9 3 R version 3 1 1 2014 07 10 Platform x86 64 apple darwin10 8 0 64 bit locale 1 en
  • 是否可以直接从文件加载镶木地板表?

    如果我有一个二进制数据文件 可以转换为 csv 格式 有什么方法可以直接从中加载镶木地板表吗 许多教程显示将 csv 文件加载到文本表 然后从文本表加载到镶木地板表 从效率的角度来看 是否可以像我已有的那样直接从二进制文件加载镶木地板表 理
  • Android html5 输入 type="password" 和数字键盘

    我的任务是为 Android 和 iOS 设计一个网页 您应该在其中输入您的信用卡信息 我无法获取在 Android 中打开数字键盘的安全代码字段 这是我距离最近的一次 它适用于 iOS 但不适用于 Android
  • 用三种颜色的渐变填充面板

    我正在做一个项目 我必须使用 C 做一种颜色选择器 所以我决定在 Win Forms 应用程序中建立一个具有此背景的面板 背景应具有 RGB 三种颜色的渐变 红色 0 255 蓝色 0 255 和绿色 0 但我找不到任何关于我应该为此使用什