2013-12-16 9 views
5

Sto provando a creare un Color Picker simile a quello di MS Paint. Sfortunatamente, non riesco a capire l'algoritmo per la saturazione. Ogni volta che cerco di implementare la saturazione, semplicemente non si saturerà correttamente. Mi manca la comprensione dell'effetto di saturazione nell'algoritmo.Cosa mi sfugge/faccio male per il mio arcobaleno Color Picker per non saturare correttamente?

enter image description here

Questo è ciò che crea il mio algoritmo corrente. Ogni volta che provo a eseguire un effetto saturo che scende sull'asse Y, rende tutto appena dopo la prima riga completamente rosso o nero.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using SFML; 
using SFML.Graphics; 
using SFML.Window; 

namespace Source 
{ 
    public ColorWheel() 
    { 
     for (int y = 0; y < 255; y++) 
     { 
      for (int z = 0; z < 6; z++) 
      { 
       for (int x = 0; x < 255; x++) 
       { 
        uint ux = (uint)x; 
        uint uy = (uint)y; 
        uint uz = (uint)z; 
        ux = ux + (uz * 255); 
        image.SetPixel(ux, uy, color); 

        //Red 255 - Green 0-254 
        if (z == 0) 
        { 
         color.G += 1; 
        } 
        //Green 255 - Red 255-0 
        else if (z == 1) 
        { 
         color.R -= 1; 
        } 
        //Green 255 - Blue 0-255 
        else if (z == 2) 
        { 
         color.B += 1; 
        } 
        //Blue 255 - Green 255-0 
        else if (z == 3) 
        { 
         color.G -= 1; 

        } 
        //Blue 255 - Red 0-255 
        else if (z == 4) 
        { 
         color.R += 1; 
        } 
        //Red 255 - Blue 255-0 
        else if (z == 5) 
        { 
         color.B -= 1; 
        } 

     Texture texture = new Texture(image); 
     sprite.Texture = texture; 
    } 

    public void Update(double dt) 
    { 
    } 

    public void Render(RenderWindow rWindow) 
    { 
     rWindow.Draw(sprite); 
    } 

} 

}

+0

Ho semplificato l'algoritmo per la barra arcobaleno. Quando ho provato a saturare, ha fatto turbinii grigi dappertutto, oops! – uFootball8

risposta

2

ho trovato questo una sfida molto interessante. Mi ci è voluto un po ', ma penso di aver capito. A quanto pare, la parte più delicata si sta rendendo conto che mentre sulla linea 1 i colori vanno da 255 a 0, ogni riga consecutiva ha meno colori (mentre si fondono lentamente con il bianco).

Quindi, per esempio, riga 10, hai 255 pixel e 245 colori disponibili per riempirli. Comunque, ecco il codice:

for (int y = 0; y < 255; y++) 
     { 
      color = new Color((255), y, y); 
      for (int z = 0; z < 6; z++) 
      { 
       for (int x = 0; x < 255; x++) 
       { 
        float colorDif = (255/((float)255 - y)); 
        uint ux = (uint)x; 
        uint uy = (uint)y; 
        uint uz = (uint)z; 
        ux = ux + (uz * 255); 
        image.SetPixel(ux, uy, color); 

        if (x >= lastX + colorDif) 
        { 
         //Red 255 - Green 0-254 
         if (z == 0) 
         { 
          if (color.G < (255)) 
           color.G += 1; 
         } 
         //Green 255 - Red 255-0 
         else if (z == 1) 
         { 
          if (color.R > y) 
           color.R -= 1; 
         } 
         //Green 255 - Blue 0-255 
         else if (z == 2) 
         { 
          if (color.B < (255)) 
           color.B += 1; 
         } 
         //Blue 255 - Green 255-0 
         else if (z == 3) 
         { 
          if (color.G > y) 
           color.G -= 1; 
         } 
         //Blue 255 - Red 0-255 
         else if (z == 4) 
         { 
          if (color.R < (255)) 
           color.R += 1; 
         } 
         //Red 255 - Blue 255-0 
         else if (z == 5) 
         { 
          if (color.B > y) 
           color.B -= 1; 
         } 
         lastX += colorDif; 
        } 
       } 
       lastX = 0; 
      } 
     } 

sembrava funzionare abbastanza bene per me, ma se ci sono problemi, fammi sapere e mi prendo un'altra occhiata. Spero che sia d'aiuto!

EDIT: e un po 'più esplicativo, per ogni evenienza. Ciò che si ottiene è di far passare i colori dal colore pieno al bianco (che è ciò che cambierà la saturazione). Ma nel caso in cui non fosse quello che intendevi, ci sono altre due varianti che dovrebbero funzionare altrettanto bene.

Se si desidera che tutti si fondono al nero, tutto ciò che serve per cambiare è il colore minima y-0 e il colore massima 255-255-y.

Si può anche mescolare al grigio, nel qual caso è necessario sia max come 255-y, min come y e colorDif = (255/((float)255 - 2 * y)); (notare il 2 *). Con il grigio tuttavia otterrai solo 127 linee di colore, anziché 255. Se questo non ha senso, posso provare a spiegare ulteriormente: P

+0

Questo è ESATTAMENTE quello per cui ero gong! Grazie! :) Questo non richiede andare in HSL, quindi ti limiti con RGB! Lo trovo molto interessante. Sapevo di essere vicino, ma non riuscivo a capire quell'ultima parte. Grazie! – uFootball8

+0

Non sono sicuro di cambiarlo per sfumare in nero o grigio. http://pastebin.com/sRevMDyr non crea il nero, crea uno strano colorwheel. La fusione con il bianco funziona perfettamente però. Sto ancora cercando di capirlo da me, hehe. – uFootball8

1

Grazie a voi Steven Mills.

E qui c'è un altro modo per farlo, il codice che ho trovato con HSL.

Ecco la risposta. Per favore usa questo come meglio credi, dato che sono felice di pubblicare una classe lavoratrice che creerà un Color Picker per chiunque usi C# e SFML.net, ma fornirà anche la logica per chiunque desideri creare un Color Picker per C# solo.

La soluzione è semplice: http://richnewman.wordpress.com/about/code-listings-and-diagrams/hslcolor-class/

1) Aggiungere la classe HSLColor dal link qui sopra.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

using SFML; 
using SFML.Graphics; 
using SFML.Window; 

namespace Source 
{ 
class ColorWheel : IGameObject 
{ 
    Image image = new Image(240, 220); 
    HSLColor hslColor = new HSLColor(); 
    System.Drawing.Color systemColor = new System.Drawing.Color(); 
    Color pixelcolor = new Color(); 
    public Sprite sprite = new Sprite(); 

    public ColorWheel() 
    { 
     pixelcolor = Color.Red; 
     hslColor.SetRGB(pixelcolor.R, pixelcolor.G, pixelcolor.B); 

     for (int y = 0; y < 220; y++) 
     { 
      //pixelcolor = Color.Red; 
      //hslColor.SetRGB(pixelcolor.R, pixelcolor.G, pixelcolor.B); 
      hslColor.Hue = 0; 
       for (int x = 0; x < 240; x++) 
       { 
        systemColor = hslColor; 
        pixelcolor.R = systemColor.R; 
        pixelcolor.G = systemColor.G; 
        pixelcolor.B = systemColor.B; 
        image.SetPixel((uint)x, (uint)y, pixelcolor); 
        hslColor.Hue += 1; 
       } 
       hslColor.Saturation -= (y * 0.01); 

     } 

     Texture texture = new Texture(image); 
     sprite.Texture = texture; 
    } 


    public void Update(double dt) 
    { 
    } 

    public void Render(RenderWindow rWindow) 
    { 
     rWindow.Draw(sprite); 
    } 

} 
} 

Ed ecco l'immagine risultante, che è possibile utilizzare liberamente per tutto ciò che si desidera. Non hai nemmeno bisogno di usare la classe ColorWheel, ma semplicemente usa questa immagine e ottieni il pixel nella posizione del mouse per tingere i tuoi oggetti di gioco come meglio credi.

enter image description here

per modificare la luminosità (che sarebbe sul cursore) usa hslColor.Luminosity nell'equazione, e probabilmente sarebbe meglio usare la classe Colorwheel anziché l'immagine, a meno che non ci si sente sicuri di regolazione la luminosità dell'immagine basata su un numero intero doppio collegato al cursore. Una buona GUI Color Picker che include sia l'immagine, il cursore del mouse e il cursore con solo poche righe di codice sarebbe TGUI. Ovviamente vorrete sostituire l'immagine di default con la classe ColorWheel se la state usando, o l'immagine ColorWheel che ho appena fornito.

Tutti gratuiti per essere utilizzati da chiunque a loro piaccia.

Problemi correlati