2015-05-20 13 views
5

Pracuję nad projektem i muszę zrobić rodzaj próbnika kolorów przy użyciu C#.Wypełnij Panel z gradientem w trzech kolorach

Zdecydowałem, że będzie to Panel z tym tłem w aplikacji Win Forms.

Tło powinno mieć gradientu z trzech kolorów RGB: czerwony (0 - 255), niebieski (0 - 255) i zielony = 0.

gu0oJ.png

Ale nie mogę znaleźć żadnych informacji na temat co powinienem użyć do tego.

Próbowałem napisać kod i oto, co zrobiłem.

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

}

A teraz mam panel z tego gradientu

ORnzf.png

Co powinienem użyć, aby uzyskać gradientu na pierwszym zdjęciu?

Drugie pytanie: Co należy zrobić, aby uzyskać piksel po kliknięciu tego tła?

+0

Również ten link może pomóc odpowiedzieć na niektóre pytania: https://msdn.microsoft.com/en-us/magazine/cc164113.aspx –

+0

Zobacz moją zaktualizowaną odpowiedź ..! – TaW

Odpowiedz

10

Oto przykład za korzystanie Multicolor LinearGradientBrush w przypadku Paint:

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

enter image description here

Można dowolnie zmieniać liczbę kolorów, kąt lub rozprzestrzenianie punktów oporowych. Tylko upewnij się, że zawsze mają taką samą liczbę kolorów i punktów zatrzymania i niech zaczynają się od 0 i kończy się o 1.

Kolory w konstruktorze są ignorowane, btw ..

Aby uzyskać klikniętego kolor można Kodeksu MouseClick:

Color clickedColor = Color.Empty; 

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

Jeśli chcesz złapać wiele kliknięć może lepiej zachować Bitmap w zmiennej poziomie klasy zamiast odtwarzając go cały czas .. Ustawienie go jako BackgroundImage Panelu, jak Kala użytkownika odpowiedzi mogą również być dobrym rozwiązaniem ..

To powinno odpowiedzieć na pytanie w tytule. Jednak twój pierwszy obraz nie pokazuje gradientu z trzema kolorami. Pokazuje gradient 2D z czterema kolorami. W przypadku tak droższej metody kolorowania należy umieścić kolory w postaci Bitmap i ustawić jako Panel 's BackgroundImage ..

Aktualizacja Oto fragment kodu, który tworzy 2D gradient:

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

Oto jak go używać:

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

wykorzystuje Ten prosty LinearGradientBrushes bez dodatkowej listy kolorów dzieje w dół na wysokości Panel.

Należy zauważyć, że Color.Green jest raczej ciemnym odcieniem, więc użyłem FromRgb dla jaśniejszego zielonego. Jeśli twój Panel jest większy niż 256 pikseli, możesz chcieć optymalizować, wypełniając większe paski; IFS jest pionowy może chcesz zmienić pętli przejść x zamiast y ..

Oto wynik:

enter image description here

Aby odebrać za pomocą kliknięcia teraz po prostu odczytać kolor od BackgroundImage:

private void panel4_MouseClick(object sender, MouseEventArgs e) 
{ 
    clickedColor = ((Bitmap)panel4.BackgroundImage).GetPixel(e.X, e.Y); 
} 
+0

wielkie dzięki, człowieku! – Buga1234

2

Z kliknięciem myszki argumentu zdarzenie E, można uzyskać punkt z dokładnymi współrzędnymi kliknięciem:

Point clickPoint = e.GetPosition(backgroundControlWithImg); 

Następnie uzyskać kolor obrazu w tej pozycji za pomocą mniej więcej tak:

System.Drawing.Image image = backgroundControl.BackgroundImage; 
Bitmap _bitmap = new Bitmap(image); 
Color _color = bitmap.GetPixel(Point.x, Point.y); 

Coś w tym stylu. Czego używasz do selektora kolorów, WPF lub?

+0

dzięki fot odpowiedź, Ok z kliknięciem zrozumiałem, jak to działa. Głównym problemem jest wykonanie tego panelu z gradientem. Czy masz jakieś rozwiązania? Używam Windows Forms nie WPF, ale mogę spróbować zrobić to w WPF, jeśli istnieje pewne rozwiązanie – Buga1234