2017-01-21 6 views
3

Мне нужно загрузить изображение с зеленым кругом на прозрачном фоне в растровое изображение с помощью 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; 
} 
+1

Добавлен пример кода. – Lamar

+0

@Lamar спасибо. Голосование убрано :) – MickyD

+0

Или [см. Здесь] (http://stackoverflow.com/questions/28847270/c-sharp-recolored-image-pixelated/28849281?s=9|0.0530#28849281)! – TaW

ответ

3

Это создаст новый Bitmap со всеми непрозрачных пикселов двигались сильно к новому цвету:

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

действительно убедитесь, что не просочиться в Bitmaps вы творите!

Обратите внимание, что есть и другие методы. Here - ссылка на метод, который использует ColorMapping. Это позволяет использовать диапазоны цветов для других диапазонов, поэтому они могут сохранять градиенты, подобные тем, которые вы получаете в антиализованной графике.

+0

Спасибо! Мне понравилось следовать вашим ссылкам stackoverflow. Тем не менее, я применил «Color.Gold» к красному изображению, но он создал еще один оттенок красного. Я понимаю RGB, но не другие массивы WA в матрице. – Lamar

+0

Работала сейчас, пожалуйста, проверьте мое обновление. Большое спасибо! – Lamar

+0

Большое спасибо! Я тестировал цвета, которые действительно работали с моей версией, но ваш код действительно прав. Я обновил свой ответ. – TaW

-2

Вот мое решение вам просто нужно создать новый элемент управления

затем наследуйте Picturebox, проверьте это.

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

} 
+0

OP хочет нарисовать растровое изображение, а не форму вектора. Кроме того, рисование в 'OnResize' является довольно unusal – MickyD

+0

У меня нет пользовательского интерфейса или элементов управления для этого. Мне просто нужно отредактировать изображение. – Lamar

+0

@ Lamar я вижу, что я не мог помочь .. извините – mardagz