【问题标题】:Change image color with transparent background使用透明背景更改图像颜色
【发布时间】:2017-06-06 05:41:09
【问题描述】:

我需要使用 c# (System.Drawings) 将透明背景上带有绿色圆圈的图像加载到位图图像中。

这是最简单的部分。但是我需要在将圆圈添加到更大的图像之前更改圆圈的颜色,而不影响周围的透明度。就我而言,我需要将圆圈颜色更改为黄色并将其添加为太阳。

我不能使用固定的黄色圆圈图像,因为所需的颜色是动态的。

那么在下面的代码中,如何在将图像添加到位图之前更改图像的颜色?

Image i = Image.FromFile(greenCircleFile);
Bitmap b = new Bitmap(500, 500);

using(Graphics g = Graphics.FromImage(b))
{
    //--> Here I need to change the color of the green circle to yellow
    //afterwards I can add it to the bitmap image
    g.DrawImage(i, 0, 0, 500, 500);
}

请注意,需要考虑两件事:保持形状(圆形)的抗锯齿,颜色需要用户自己选择并按原样使用来覆盖圆形的原始颜色。

固定:

感谢@TaW,他提供了正确答案。但是有一个小故障,这是对我有用的最终版本:

Image i = Image.FromFile(greenCircleFile);
Bitmap b = new Bitmap(500, 500);

using(Graphics g = Graphics.FromImage(b))
{
    //Here I need to change the color of the green circle to yellow
    i = ChangeToColor(b, Color.Gold)
    //afterwards I can add it to the bitmap image
    g.DrawImage(i, 0, 0, 500, 500);
}

而ChangeToColor函数如下:

Bitmap ChangeToColor(Bitmap bmp, Color c)
{
    Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height);
    using (Graphics g = Graphics.FromImage(bmp2))
    {
        float tr = c.R / 255f;
        float tg = c.G / 255f;
        float tb = c.B / 255f;

        ColorMatrix colorMatrix = new ColorMatrix(new float[][]
          {
            new float[] {0, 0, 0, 0, 0},
            new float[] {0, 0, 0, 0, 0},
            new float[] {0, 0, 0, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {tr, tg, tb, 0, 1}
          });

        ImageAttributes attributes = new ImageAttributes();
        attributes.SetColorMatrix(colorMatrix);

        g.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height),
            0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attributes);
    }
    return bmp2;
}

【问题讨论】:

  • 添加了示例代码。
  • @Lamar 谢谢。投票撤回:)
  • see here!

标签: c# gdi+ system.drawing


【解决方案1】:

这将创建一个新的位图,其中所有非透明像素都向新颜色强烈移动:

    Bitmap ChangeToColor(Bitmap bmp, Color c)
    {
        Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height);
        using (Graphics g = Graphics.FromImage(bmp2))
        {
            float tr = c.R / 255f;
            float tg = c.G / 255f;
            float tb = c.B / 255f;

            ColorMatrix colorMatrix = new ColorMatrix(new float[][]
              {
                 new float[] {0, 0, 0, 0, 0},
                 new float[] {0, 0, 0, 0, 0},
                 new float[] {0, 0, 0, 0, 0},
                 new float[] {0, 0, 0, 1, 0},
                 new float[] {tr, tg, tb, 0, 1}  // kudos to OP!
              });

            ImageAttributes attributes = new ImageAttributes();
            attributes.SetColorMatrix(colorMatrix);

            g.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height),
                0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attributes);
        }
        return bmp2;
    }

请确保不要泄露您创建的位图!

请注意,还有其他方法。 Here 是一个使用ColorMapping 的方法的链接。这允许将一系列颜色替换为另一个范围,因此它可以保持与您在反锯齿图形中获得的渐变一样的渐变..

【讨论】:

  • 谢谢!我喜欢关注您的 stackoverflow 参考资料。但是,我将“Color.Gold”应用于红色图像,但它产生了另一种红色。我了解 RGB,但不了解矩阵中的其他 WA 数组。
  • 非常感谢!!我已经用我的版本确实有效的颜色进行了测试,但你的代码确实是正确的。我已经更新了我的答案。
  • 我试过了,但它似乎将整个图像替换为一种颜色,而不是仅仅替换指定的颜色。
【解决方案2】:

这是我的解决方案,您只需要创建一个新控件

然后继承图片框检查一下。

public partial class UICirclePicture : PictureBox
{
    [Browsable(false)]
    public int Depth { get; set; }
    [Browsable(false)]
    public SprikiwikiUI Ui
    {
        get { return SprikiwikiUI.Instance; }
    }
    [Browsable(false)]
    public MouseState MouseState { get; set; }

    public UICirclePicture()
    {


        BackColor = Ui.GetApplicationBackgroundColor();
        SizeMode = PictureBoxSizeMode.StretchImage;

    }


    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
        using (var gp = new GraphicsPath())
        {
            gp.AddEllipse(new Rectangle(0, 0, this.Width - 1, this.Height - 1));
            this.Region = new Region(gp);
        }
    }

}

【讨论】:

  • OP 想要绘制光栅图像而不是矢量形状。此外,在OnResize 中绘图是相当不寻常的
  • 我没有相应的用户界面或控件。我只需要编辑一张图片。
  • @Lamar 我明白了,我帮不上忙……抱歉
猜你喜欢
  • 1970-01-01
  • 2014-07-12
  • 1970-01-01
  • 2015-01-07
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多