用透明背景更改图像颜色

我需要使用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); } 

而ChangeToColorfunction如下:

 Bitmap ChangeToColor(Bitmap bmp, Color c) { Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height); using (Graphics g = Graphics.FromImage(bmp2)) { float tr = cR / 255f; float tg = cG / 255f; float tb = cB / 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; } 

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

  Bitmap ChangeToColor(Bitmap bmp, Color c) { Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height); using (Graphics g = Graphics.FromImage(bmp2)) { float tr = cR / 255f; float tg = cG / 255f; float tb = cB / 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; } 

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

请注意,还有其他方法。 以下是使用ColorMapping的方法的链接。 这允许一系列颜色被另一个范围替换,因此它可以保持渐变像你在反对图形中获得的渐变。

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

然后inheritancePicturebox检查出来。

 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); } } }