【问题标题】:How to put some color on image如何在图像上添加一些颜色
【发布时间】:2017-11-20 18:51:01
【问题描述】:

我这里有圆形图像,我想做的是在特定位置放置一些颜色。例如,当我点击button1时,圆圈的左侧将被红色填充,当我点击button2,右边也会被填充,当我再次点击button1时,颜色会被移除,以此类推...

我对此进行了一些研究,并找到了两种方法。首先是用另一个图像覆盖圆圈。二是绘制,使用C#中的Graphics类..

现在,我的问题是,还有其他可能的方法吗?最好的方法是什么?

P.S: 这样做的目的是为了牙图。 :)

【问题讨论】:

  • 你能告诉我们你的代码吗?
  • 使用多张图片可能是最简单的方法。
  • 方法很多很多。 “最佳”取决于您拥有的规格,不,“牙齿图表”对我们来说不是有用的规格。一个基本问题是:你能从几何上描述这个形状吗?他们(在你的情况下)5 GraphicsPaths 显然是最好的选择。如果你不能,你可以实现一个floodfill..看看this post,看看你是否适合你的情况!其他posts you might find useful..
  • 也看看这个,rather similar post!

标签: c# winforms graphics colors picturebox


【解决方案1】:

这是一个基于 qing 的帖子的 Resizable, Clickable, UserControl。您可以直接单击区域进行切换,也可以通过代码更改它们。

public partial class ToothChart : UserControl
{

    public ToothChart()
    {
        InitializeComponent();
        this.DoubleBuffered = true;
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        if (this.ParentForm != null)
        {
            this.ParentForm.FormClosing += (s, evt) => { OnHandleDestroyed(new EventArgs()); };
        }
    }

    protected override void OnHandleDestroyed(EventArgs e)
    {
        base.OnHandleDestroyed(e);

        if (this._pathTop != null)
        {
            this._pathTop.Dispose();
            this._pathTop = null;
        }
        if (this._pathRight != null)
        {
            this._pathRight.Dispose();
            this._pathRight = null;
        }
        if (this._pathBottom != null)
        {
            this._pathBottom.Dispose();
            this._pathBottom = null;
        }
        if (this._pathLeft != null)
        {
            this._pathLeft.Dispose();
            this._pathLeft = null;
        }
        if (this._pathCenter != null)
        {
            this._pathCenter.Dispose();
            this._pathCenter = null;
        }
    }

    private GraphicsPath _pathTop = null;
    private GraphicsPath _pathLeft = null;
    private GraphicsPath _pathBottom = null;
    private GraphicsPath _pathRight = null;
    private GraphicsPath _pathCenter = null;

    private bool _TopRegion = false;
    public bool TopRegion
    {
        get
        {
            return _TopRegion;
        }
        set
        {
            if (_TopRegion != value)
            {
                _TopRegion = value;
                this.Invalidate();
            }
        }
    }

    private bool _RightRegion = false;
    public bool RightRegion
    {
        get
        {
            return _RightRegion;
        }
        set
        {
            if (_RightRegion != value)
            {
                _RightRegion = value;
                this.Invalidate();
            }
        }
    }

    private bool _BottomRegion = false;
    public bool BottomRegion
    {
        get
        {
            return _BottomRegion;
        }
        set
        {
            if (_BottomRegion != value)
            {
                _BottomRegion = value;
                this.Invalidate();
            }
        }
    }

    private bool _LeftRegion = false;
    public bool LeftRegion
    {
        get
        {
            return _LeftRegion;
        }
        set
        {
            if (_LeftRegion != value)
            {
                _LeftRegion = value;
                this.Invalidate();
            }
        }
    }

    private bool _CenterRegion = false;
    public bool CenterRegion
    {
        get
        {
            return _CenterRegion;
        }
        set
        {
            if (_CenterRegion != value)
            {
                _CenterRegion = value;
                this.Invalidate();
            }
        }
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        if (this.IsHandleCreated && this._pathTop != null)
        {
            this.UpdateRegions();
        }
    }

    private void UpdateRegions()
    {
        int diameterBig = Math.Min(this.Width, this.Height) - 10;
        int diameterSmall = Math.Min(this.Width, this.Height) / 3;
        if (diameterBig > 0 && diameterSmall > 0)
        {
            Point _centerPoint = new Point(this.Width / 2, this.Height / 2);
            Rectangle rectangle = new Rectangle(_centerPoint.X - diameterBig / 2, _centerPoint.Y - diameterBig / 2, diameterBig, diameterBig);
            Rectangle rectangle2 = new Rectangle(_centerPoint.X - diameterSmall / 2, _centerPoint.Y - diameterSmall / 2, diameterSmall, diameterSmall);

            _pathTop.Reset();
            _pathTop.AddArc(rectangle, 225, 90);
            _pathTop.AddArc(rectangle2, -45, -90);

            _pathLeft.Reset();
            _pathLeft.AddArc(rectangle, 135, 90);
            _pathLeft.AddArc(rectangle2, -135, -90);

            _pathBottom.Reset();
            _pathBottom.AddArc(rectangle, 45, 90);
            _pathBottom.AddArc(rectangle2, -225, -90);

            _pathRight.Reset();
            _pathRight.AddArc(rectangle, -45, 90);
            _pathRight.AddArc(rectangle2, -315, -90);

            _pathCenter.Reset();
            _pathCenter.AddEllipse(rectangle2);

            this.Invalidate();
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (this.IsHandleCreated)
        {
            if (this._pathTop == null)
            {
                this._pathTop = new GraphicsPath();
                this._pathRight = new GraphicsPath();
                this._pathBottom = new GraphicsPath();
                this._pathLeft = new GraphicsPath();
                this._pathCenter = new GraphicsPath();
                this.UpdateRegions();
            }

            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            if (this.TopRegion)
            {
                e.Graphics.FillPath(Brushes.Blue, _pathTop);
            }
            e.Graphics.DrawPath(Pens.Black, _pathTop);

            if (this.RightRegion)
            {
                e.Graphics.FillPath(Brushes.DarkRed, _pathRight);
            }
            e.Graphics.DrawPath(Pens.Black, _pathRight);

            if (this.BottomRegion)
            {
                e.Graphics.FillPath(Brushes.Teal, _pathBottom);
            }
            e.Graphics.DrawPath(Pens.Black, _pathBottom);

            if (this.LeftRegion)
            {
                e.Graphics.FillPath(Brushes.Yellow, _pathLeft);
            }
            e.Graphics.DrawPath(Pens.Black, _pathLeft);

            if (this.CenterRegion)
            {
                e.Graphics.FillPath(Brushes.LightGreen, _pathCenter);
            }
            e.Graphics.DrawPath(Pens.Black, _pathCenter);
        }         
    }

    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);

        Point p = new Point(e.X, e.Y);

        if (this._pathTop.IsVisible(p))
        {
            this.TopRegion = !this.TopRegion;
        }
        else if (this._pathRight.IsVisible(p))
        {
            this.RightRegion = !this.RightRegion;
        }
        else if (this._pathBottom.IsVisible(p))
        {
            this.BottomRegion = !this.BottomRegion;
        }
        else if (this._pathLeft.IsVisible(p))
        {
            this.LeftRegion = !this.LeftRegion;
        }
        else if (this._pathCenter.IsVisible(p))
        {
            this.CenterRegion = !this.CenterRegion;
        }
    }

}

【讨论】:

  • 嗨@Idle_Mind,实际上我正在尝试理解您的代码,但对我来说似乎有点难。我已经尝试过了,它奏效了。你介意我问吗,如果我也想在圆圈上添加颜色怎么办?
  • 你是说内圈,中间圈?你想要它只是彩色的,还是可点击的?
  • 这里有好东西。我通常不赞成用预先编写的代码和没有解释的勺子喂养的答案,但这是相当高质量的工作。我建议的唯一一件事是覆盖 Dispose(控件实现 IDisposable)并确保释放存储为成员变量的 GraphicsPath 对象。这不会自动发生,并且 GraphicsPath 对象不是从 System.ComponentModel.Component 派生的,因此您不能简单地将它们添加到 Control 的 Components 集合中,以便由基类的 Dispose 方法自动释放它们,因此您需要自己做。
  • @Idle_Mind,我希望圆圈也像其他边一样是可点击的。
  • 更新了代码,使中心区域现在可以点击,还包括处理正确处置 GraphicsPath 实例的代码,如@CodyGray 所建议的那样。
猜你喜欢
  • 2020-05-07
  • 2012-02-20
  • 1970-01-01
  • 2018-06-10
  • 2019-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
相关资源
最近更新 更多