我的彩虹拾色器不能正确饱和,我错过了什么/做错了什么?

时间:2013-12-16 16:50:52

标签: c# user-interface colors sfml

我正在尝试创建一个类似于MS Paint的拾色器。 不幸的是,我无法弄清楚饱和算法。 每当我尝试实现饱和度时,它都不会正确饱和。 我不得不对算法中的饱和效应有所了解。

enter image description here

这是我当前算法创建的。 无论何时我尝试在Y轴上执行饱和效果,它只会使第一行之后的所有内容完全变为红色或黑色。

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

}

}

2 个答案:

答案 0 :(得分:2)

我发现这是一个非常有趣的挑战。花了我一会儿,但我想我想通了。棘手的部分显然意识到,在第1行,颜色介于255和0之间,每个连续的行都有较少的颜色(因为它们慢慢地混合为白色)。

因此,在第10行,你有255个像素,有245种颜色可以填充它们。无论如何,这是代码:

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

它对我来说似乎很有效,但是如果有任何问题,lemme知道,我会再看看它。希望它有所帮助!

编辑:并进一步解释,以防万一。这样做的目的是使颜色从全彩色变为白色(这就是改变饱和度所做的)。但是,如果这不是你的意思,还有另外两个变化也应该起作用。

如果您希望将所有内容混合为黑色,则需要更改的是从y0的最小颜色以及从255255-y的最大颜色

您也可以混合为灰色,在这种情况下,您需要最多为255-y,最小为ycolorDif = (255 / ((float)255 - 2 * y));(请注意2 *)。但是使用灰色,你只能获得127行颜色,而不是255行。如果这没有意义,我可以尝试进一步解释:P

答案 1 :(得分:1)

谢谢Steven Mills。

这是另一种方法,我提出的使用HSL的代码。

这是答案。请自由地使用这个,因为我很高兴发布一个工作类,它将为使用C#和SFML.net的任何人创建一个拾色器,但也为希望为C#创建拾色器的任何人提供逻辑仅

解决方案很简单: http://richnewman.wordpress.com/about/code-listings-and-diagrams/hslcolor-class/

1)从上面的链接添加HSLColor类。

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

}
}

以下是生成的图像,您可以自由地将其用于任何您想要的图像。您甚至不需要使用ColorWheel类,只需使用此图像并获取鼠标位置的像素即可根据需要对游戏对象进行染色。

enter image description here

要更改亮度(将在滑块上),请使用等式中的hslColor.Luminosity,最好使用ColorWheel类而不是图像,除非您有信心根据a调整图像亮度附加到滑块的双整数。 一个好的拾色器GUI,包括图像,鼠标光标和只有几行代码的滑块,将是TGUI。显然,如果您使用ColorWheel类,或者我刚刚提供的ColorWheel图像,您可能希望用ColorWheel类替换默认图像。

所有人都可以随意使用。