2015-05-20 15 views
5

Sto lavorando al progetto e devo fare una sorta di selezione colori usando C#.Riempi pannello con gradiente in tre colori

Quindi ho deciso che sarà un pannello con questo sfondo in Win Form App.

sfondo dovrebbe avere gradiente con tre colori in RGB: rosso (0 - 255), blu (0 - 255) e verde = 0.

gu0oJ.png

Ma non riesco a trovare tutte le informazioni su cosa dovrei usare per questo.

Ho provato a scrivere del codice ed ecco cosa ho fatto.

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

}

e ora ho pannello con il gradiente

ORnzf.png

Cosa devo usare per ottenere gradiente alla prima immagine?

E seconda domanda: cosa devo fare per ottenere il colore del pixel dopo aver fatto clic su questo sfondo?

+0

Inoltre, questo link potrebbe aiutare a rispondere alle vostre domande: https://msdn.microsoft.com/en-us/magazine/cc164113.aspx –

+0

Vedere la mia risposta aggiornato ..! – TaW

risposta

10

Ecco un esempio di utilizzo di un multicolore LinearGradientBrush nel caso 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

Si può liberamente variare il numero di colori, l'angolo o la diffusione dei punti di arresto. Basta fare in modo di avere sempre lo stesso numero di colori e smettere di punti e far loro partono da 0 e terminano alle 1.

I colori nel costruttore vengono ignorati, btw ..

per ottenere un colore cliccato si può codificare il 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); 
    } 
} 

Se si desidera catturare il numero di clic può essere meglio per mantenere il Bitmap in una variabile livello di classe, invece di ricreare tutto il tempo .. Impostazione come BackgroundImage del panel, come Kala di la risposta assume potrebbe anche essere una buona opzione ..

Questo dovrebbe rispondere alla domanda nel titolo. Tuttavia la tua prima immagine non mostra una sfumatura con tre colori. Mostra un gradiente 2D con quattro colori. Per un metodo di colorazione così costoso dovresti inserire i colori in un Bitmap e impostarlo come BackgroundImagePanel ..

aggiornamento Ecco un pezzo di codice che crea un gradiente 2D:

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

Ecco come lo si utilizza:

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

Questo utilizza semplice LinearGradientBrushes senza una lista di colori in più che va giù sopra l'altezza del Panel.

Si noti che Color.Green è una tonalità piuttosto scura, quindi ho utilizzato FromRgb per un verde più luminoso. Se il tuo Panel è superiore a 256 pixel, potresti voler eseguire l'ottimizzazione riempendo strisce più grandi; IFS è verticale, si può decidere di cambiare il ciclo di andare oltre x invece di y ..

Ecco il risultato:

enter image description here

Per raccogliere con un click ora semplicemente leggere il colore dal BackgroundImage:

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

grazie mille, amico! – Buga1234

2

Dal clic del mouse argomento evento e, si può ottenere il punto con le esatte coordinate del clic:

Point clickPoint = e.GetPosition(backgroundControlWithImg); 

quindi ottenere il colore dell'immagine in quella posizione usando qualcosa come:

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

Qualcosa del genere. Cosa stai usando per Color Picker, WPF o?

+0

grazie per la risposta, Ok col click ho capito come funziona. Il problema principale è fare questo pannello con il gradiente. Avete qualche soluzione per questo? Sto usando Windows Forms non WPF, ma posso provare a farlo in WPF se c'è qualche soluzione – Buga1234