コード例 #1
0
        protected void AddColorItem(int red, int green, int blue)
        {
            Color             c    = Color.FromArgb(red, green, blue);
            ToolStripMenuItem item = new ToolStripMenuItem();

            item.BackColor = c;
            item.Text      = String.Format("{0}, {1}, {2}", red, green, blue);
            item.Click    += new EventHandler(refColorMenuItem_Click);
            refColorMenu.Items.Add(item);

            refColors.Add(HSVColor.FromRGB(red, green, blue));
        }
コード例 #2
0
        public float[] DistanceToCenters(HSVColor color)
        {
            float[] ret = new float[centers.Length];
            Point   p   = color.HSCartesian;

            for (int i = 0; i < centers.Length; i++)
            {
                ret[i] = centers[i].Distance(p);
            }

            return(ret);
        }
コード例 #3
0
        protected HSVColor AverageColor()
        {
            // rotate the colors around so that color0 is at h=180 before averaging
            float normDiff = 180f - baseColors[0].H;

            HSVColor[] normColors = new HSVColor[4];
            for (int i = 0; i < 4; i++)
            {
                float nh = baseColors[i].H + normDiff;
                if (nh < 0f)
                {
                    nh = nh + 360f;
                }
                if (nh >= 360f)
                {
                    nh = nh - 360f;
                }
                normColors[i] = new HSVColor(nh, baseColors[i].S, baseColors[i].V);
            }

            // compute average color
            float avH = 0f;
            float avS = 0f;
            float avV = 0f;

            for (int i = 0; i < 4; i++)
            {
                avH = avH + normColors[i].H;
                avS = avS + normColors[i].S;
                avV = avV + normColors[i].V;
            }

            avH = avH / 4f;
            avS = avS / 4f;
            avV = avV / 4f;

            // shift H back to original location
            avH = avH - normDiff;
            if (avH < 0f)
            {
                avH = avH + 360f;
            }
            if (avH >= 360f)
            {
                avH = avH - 360f;
            }

            return(new HSVColor(avH, avS, avV));
        }
コード例 #4
0
 public ColorInfo(int kmIndex, float minV, float maxV, HSVColor hsv)
 {
     this.kmIndex = kmIndex;
     this.minV    = minV;
     this.maxV    = maxV;
     midV         = (maxV + minV) / 2.0f;
     if (midV == 0.0f)
     {
         Vmult = 0.0f;
     }
     else
     {
         Vmult = 0.5f / midV;
     }
     this.hsv = new HSVColor(hsv.H, hsv.S, midV);
 }
コード例 #5
0
        /// <summary>
        /// computes the distance in cartesian space between the HS components of
        ///   two colors.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public float Distance(HSVColor other)
        {
            float hrad = h * (float)Math.PI / 180.0f;

            float x1 = s * (float)Math.Cos(hrad);
            float y1 = s * (float)Math.Sin(hrad);

            hrad = other.h * (float)Math.PI / 180.0f;

            float x2 = other.s * (float)Math.Cos(hrad);
            float y2 = other.s * (float)Math.Sin(hrad);

            float xdelta = x2 - x1;
            float ydelta = y2 - y1;

            return((float)Math.Sqrt(xdelta * xdelta + ydelta * ydelta));
        }
コード例 #6
0
        public void AddEntry(string tileName, string colorName, HSVColor[] colors)
        {
            Dictionary<string, HSVColor[]> tileMap;
            library.TryGetValue(tileName, out tileMap);
            if (tileMap == null)
            {
                tileMap = new Dictionary<string, HSVColor[]>();
                library[tileName] = tileMap;
            }

            // make sure we have our own copy of the colors
            HSVColor[] newColors = new HSVColor[4];
            tileMap[colorName] = newColors;
            newColors[0] = colors[0];
            newColors[1] = colors[1];
            newColors[2] = colors[2];
            newColors[3] = colors[3];

            dirty = true;
        }
コード例 #7
0
        public void AddEntry(string tileName, string colorName, HSVColor[] colors)
        {
            Dictionary <string, HSVColor[]> tileMap;

            library.TryGetValue(tileName, out tileMap);
            if (tileMap == null)
            {
                tileMap           = new Dictionary <string, HSVColor[]>();
                library[tileName] = tileMap;
            }

            // make sure we have our own copy of the colors
            HSVColor[] newColors = new HSVColor[4];
            tileMap[colorName] = newColors;
            newColors[0]       = colors[0];
            newColors[1]       = colors[1];
            newColors[2]       = colors[2];
            newColors[3]       = colors[3];

            dirty = true;
        }
コード例 #8
0
        public int ClosestIndex(HSVColor color)
        {
            float distance;
            float minDist;
            int   minIndex;

            minDist  = lastCenters[0].Distance(color.HSCartesian);
            minIndex = 0;

            for (int i = 1; i < k; i++)
            {
                distance = lastCenters[i].Distance(color.HSCartesian);
                if (distance < minDist)
                {
                    minDist  = distance;
                    minIndex = i;
                }
            }

            return(minIndex);
        }
コード例 #9
0
        private void colorToLibraryButton_Click(object sender, EventArgs e)
        {
            HSVColor [] colors = new HSVColor[4];
            colors[0] = AdjustedColor(0);
            colors[1] = AdjustedColor(1);
            colors[2] = AdjustedColor(2);
            colors[3] = AdjustedColor(3);

            string tilename;
            string colorname;

            TreeNode selectedNode = libraryTreeView.SelectedNode;

            if (selectedNode.Tag != null)
            {
                colorname = selectedNode.Text;
                tilename  = selectedNode.Parent.Text;
            }
            else
            {
                tilename  = Path.GetFileNameWithoutExtension(currentTileName);
                colorname = "";
            }

            using (TileColorPrompt dlg = new TileColorPrompt())
            {
                dlg.TileName  = tilename;
                dlg.ColorName = colorname;
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    tilename  = dlg.TileName;
                    colorname = dlg.ColorName;

                    library.AddEntry(tilename, colorname, colors);

                    LibraryToTreeview();
                }
            }
        }
コード例 #10
0
        public Kmeans(HSVColor[] colors, int k)
        {
            r = new Random();

            this.k = k;

            centers      = new Point[k];
            lastCenters  = new Point[k];
            centerColors = new HSVColor[k];

            accumulators      = new Point[k];
            accumulatorCounts = new int[k];

            allColors = colors;

            InitCenters();

            int n = 1;

            DumpCenters(0);
            while (!FoundSolution())
            {
                ClearAccumulators();
                CopyCenters();
                for (int i = 0; i < allColors.Length; i++)
                {
                    // find closest point for this color
                    int   closest = ClosestIndex(allColors[i]);
                    Point pt      = allColors[i].HSCartesian;

                    // add this color's location to the accumulator for the closest point
                    accumulators[closest].X += pt.X;
                    accumulators[closest].Y += pt.Y;
                    accumulatorCounts[closest]++;
                }

                CalculateCenters();
                DumpCenters(n);
                n++;
            }

            // convert the colors back to HSV
            for (int i = 0; i < k; i++)
            {
                centerColors[i] = new HSVColor(centers[i]);
            }

            centerDistances = new float[k, k];

            for (int i = 0; i < k; i++)
            {
                for (int j = 0; j < k; j++)
                {
                    if (i == j)
                    {
                        centerDistances[i, j] = 0.0f;
                    }
                    else
                    {
                        centerDistances[i, j] = centers[i].Distance(centers[j]);
                    }
                }
            }
        }
コード例 #11
0
        public void FillTile(DDSFile ddsDest)
        {
            for (int y = 0; y < dds.Height; y++)
            {
                for (int x = 0; x < dds.Width; x++)
                {
                    HSVColor hsv = HSVColor.FromRGB(dds.GetPixel(x, y));

                    float[] distances = km.DistanceToCenters(hsv);
                    int     nearest, second;
                    float   nearestWeight;
                    if (distances[0] < distances[1])
                    {
                        nearest = 0;
                        second  = 1;
                    }
                    else
                    {
                        nearest = 1;
                        second  = 0;
                    }
                    if (distances[2] < distances[nearest])
                    {
                        second  = nearest;
                        nearest = 2;
                    }
                    else if (distances[2] < distances[second])
                    {
                        second = 2;
                    }
                    if (distances[3] < distances[nearest])
                    {
                        second  = nearest;
                        nearest = 3;
                    }
                    else if (distances[3] < distances[second])
                    {
                        second = 3;
                    }
                    // only weight between the two colors if the current point is nearer to each of them
                    // than they are to each other.  otherwise just weight to neartest.
                    if (km.CenterDistances[nearest, second] < distances[second])
                    {
                        nearestWeight = 1.0f;
                    }
                    else
                    {
                        nearestWeight = distances[second] / (distances[nearest] + distances[second]);
                    }

                    // init color components
                    int[] components = new int[4];
                    components[0] = 0;
                    components[1] = 0;
                    components[2] = 0;
                    components[3] = 0;

                    nearest = kmColorMap[nearest];
                    second  = kmColorMap[second];

                    components[nearest] = (int)(hsv.V * colors[nearest].VMult * 255 * nearestWeight);
                    components[second]  = (int)(hsv.V * colors[second].VMult * 255 * (1.0f - nearestWeight));
                    Color c = Color.FromArgb(components[3], components[0], components[1], components[2]);

                    int index = kmColorMap[km.ClosestIndex(hsv)];

                    ddsDest.SetColor(x, y, c);
                }
            }
        }
コード例 #12
0
        public HSVColor ClosestColor(HSVColor color)
        {
            int index = ClosestIndex(color);

            return(new HSVColor(centers[index], color.V));
        }
コード例 #13
0
        public Kmeans(HSVColor[] colors, int k)
        {
            r = new Random();

            this.k = k;

            centers = new Point[k];
            lastCenters = new Point[k];
            centerColors = new HSVColor[k];

            accumulators = new Point[k];
            accumulatorCounts = new int[k];

            allColors = colors;

            InitCenters();

            int n = 1;
            DumpCenters(0);
            while (!FoundSolution())
            {
                ClearAccumulators();
                CopyCenters();
                for (int i = 0; i < allColors.Length; i++)
                {
                    // find closest point for this color
                    int closest = ClosestIndex(allColors[i]);
                    Point pt = allColors[i].HSCartesian;

                    // add this color's location to the accumulator for the closest point
                    accumulators[closest].X += pt.X;
                    accumulators[closest].Y += pt.Y;
                    accumulatorCounts[closest]++;
                }

                CalculateCenters();
                DumpCenters(n);
                n++;
            }

            // convert the colors back to HSV
            for (int i = 0; i < k; i++)
            {
                centerColors[i] = new HSVColor(centers[i]);
            }

            centerDistances= new float[k,k];

            for (int i = 0; i < k; i++)
            {
                for (int j = 0; j < k; j++)
                {
                    if (i == j)
                    {
                        centerDistances[i,j] = 0.0f;
                    }
                    else
                    {
                        centerDistances[i,j] = centers[i].Distance(centers[j]);
                    }
                }
            }
        }
コード例 #14
0
 public void DumpCenters(int iter)
 {
     Console.WriteLine("Iteration {0}", iter);
     for (int i = 0; i < k; i++)
     {
         Console.WriteLine("  X: {0}, Y: {1}", centers[i].X, centers[i].Y);
         HSVColor color = new HSVColor(centers[i]);
         Console.WriteLine("  H: {0}, S: {1}, V: {2}", color.H, color.S, color.V);
     }
 }
コード例 #15
0
        public TileMaker(string filename, int numColors)
        {
            dds = DDSFile.LoadFile(filename);

            int numPixels = dds.Width * dds.Height;

            HSVColor[] pixels = new HSVColor[numPixels];

            // create the array of colors in this image
            int offset = 0;

            for (int y = 0; y < dds.Height; y++)
            {
                for (int x = 0; x < dds.Width; x++)
                {
                    pixels[offset] = HSVColor.FromRGB(dds.GetPixel(x, y));
                    offset++;
                }
            }

            // compute the clustering
            km = new Kmeans(pixels, numColors);

            float[] minv = new float[numColors];
            float[] maxv = new float[numColors];

            for (int i = 0; i < numColors; i++)
            {
                minv[i] = float.MaxValue;
                maxv[i] = float.MinValue;
            }

            // compute min and max v for each color cluster
            for (int y = 0; y < dds.Height; y++)
            {
                for (int x = 0; x < dds.Width; x++)
                {
                    HSVColor hsv   = HSVColor.FromRGB(dds.GetPixel(x, y));
                    int      index = km.ClosestIndex(hsv);

                    // record min and max v for each channel
                    float v = hsv.V;
                    if (v < minv[index])
                    {
                        minv[index] = v;
                    }
                    if (v > maxv[index])
                    {
                        maxv[index] = v;
                    }
                }
            }

            for (int i = 0; i < numColors; i++)
            {
                if (minv[i] == float.MaxValue)
                {
                    minv[i] = 0.0f;
                }
                if (maxv[i] == float.MinValue)
                {
                    maxv[i] = 0.0f;
                }

                ColorInfo ci = new ColorInfo(i, minv[i], maxv[i], km.CenterColors[i]);
                colors.Add(ci);
            }

            colors.Sort();

            // create the mapping from the kmeans returned colors to the sorted colors
            kmColorMap = new int[numColors];
            for (int i = 0; i < numColors; i++)
            {
                kmColorMap[colors[i].KMIndex] = i;
            }
        }
コード例 #16
0
        protected void SetAllColors(HSVColor[] colors)
        {
            for (int i = 0; i < 4; i++)
            {
                baseColors[i] = colors[i];
            }

            UpdateButtons();
            ColorizeTile();
        }
コード例 #17
0
        protected HSVColor AverageColor()
        {
            // rotate the colors around so that color0 is at h=180 before averaging
            float normDiff = 180f - baseColors[0].H;
            HSVColor[] normColors = new HSVColor[4];
            for (int i = 0; i < 4; i++)
            {
                float nh = baseColors[i].H + normDiff;
                if (nh < 0f)
                {
                    nh = nh + 360f;
                }
                if (nh >= 360f)
                {
                    nh = nh - 360f;
                }
                normColors[i] = new HSVColor(nh, baseColors[i].S, baseColors[i].V);
            }

            // compute average color
            float avH = 0f;
            float avS = 0f;
            float avV = 0f;
            for (int i = 0; i < 4; i++)
            {
                avH = avH + normColors[i].H;
                avS = avS + normColors[i].S;
                avV = avV + normColors[i].V;
            }

            avH = avH / 4f;
            avS = avS / 4f;
            avV = avV / 4f;

            // shift H back to original location
            avH = avH - normDiff;
            if (avH < 0f)
            {
                avH = avH + 360f;
            }
            if (avH >= 360f)
            {
                avH = avH - 360f;
            }

            return new HSVColor(avH, avS, avV);
        }
コード例 #18
0
        public void Load(string filename)
        {
            bool empty = (library.Count == 0);
            XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();

            XmlReader r = XmlReader.Create(filename, xmlReaderSettings);

            // read until we find the start of a tile description
            while (r.Read())
            {
                // look for the start of the tile description
                if (r.NodeType == XmlNodeType.Element)
                {
                    if (r.Name == "Tile")
                    {
                        string tileName = r.GetAttribute("Name");

                        // read until we find the start of a color description
                        while (r.Read())
                        {
                            // look for the start of the tile description
                            if (r.NodeType == XmlNodeType.Element)
                            {
                                if (r.Name == "Colors")
                                {
                                    string colorName = r.GetAttribute("Name");
                                    HSVColor[] colors = new HSVColor[4];

                                    while (r.Read())
                                    {
                                        if (r.NodeType == XmlNodeType.Element)
                                        {
                                            if (r.Name == "HSVColor")
                                            {
                                                int colorNum = int.Parse(r.GetAttribute("ColorNum"));
                                                float h = float.Parse(r.GetAttribute("H"));
                                                float s = float.Parse(r.GetAttribute("S"));
                                                float v = float.Parse(r.GetAttribute("V"));
                                                colors[colorNum] = new HSVColor(h, s, v);
                                            }
                                        }
                                        else if (r.NodeType == XmlNodeType.EndElement)
                                        {
                                            break;
                                        }
                                    }
                                    AddEntry(tileName, colorName, colors);
                                }
                            }
                            else if (r.NodeType == XmlNodeType.EndElement)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            dirty = !empty;
        }
コード例 #19
0
        protected HSVColor[] ComputeRefColors(HSVColor refColor)
        {
            HSVColor applyTo;

            switch (refColorMode)
            {
            case RefColorMode.Average:
            default:
                applyTo = AverageColor();
                break;

            case RefColorMode.Color0:
                applyTo = baseColors[0];
                break;

            case RefColorMode.Color1:
                applyTo = baseColors[1];
                break;

            case RefColorMode.Color2:
                applyTo = baseColors[2];
                break;

            case RefColorMode.Color3:
                applyTo = baseColors[3];
                break;
            }

            float deltaH = refColor.H - applyTo.H;
            float deltaS = refColor.S - applyTo.S;

            HSVColor[] retColors = new HSVColor[4];

            for (int i = 0; i < 4; i++)
            {
                float h = baseColors[i].H + deltaH;
                float s = baseColors[i].S + deltaS;

                // keep h in [0..360)
                while (h < 0f)
                {
                    h = h + 360f;
                }
                while (h >= 360f)
                {
                    h = h - 360f;
                }

                // clamp s to [0..1]
                if (s > 1f)
                {
                    s = 1f;
                }
                if (s < 0f)
                {
                    s = 0f;
                }

                retColors[i] = new HSVColor(h, s, baseColors[i].V);
            }
            return(retColors);
        }
コード例 #20
0
        protected HSVColor[] ComputeRefColors(HSVColor refColor)
        {
            HSVColor applyTo;

            switch (refColorMode)
            {
                case RefColorMode.Average:
                default:
                    applyTo = AverageColor();
                    break;
                case RefColorMode.Color0:
                    applyTo = baseColors[0];
                    break;
                case RefColorMode.Color1:
                    applyTo = baseColors[1];
                    break;
                case RefColorMode.Color2:
                    applyTo = baseColors[2];
                    break;
                case RefColorMode.Color3:
                    applyTo = baseColors[3];
                    break;
            }

            float deltaH = refColor.H - applyTo.H;
            float deltaS = refColor.S - applyTo.S;

            HSVColor[] retColors = new HSVColor[4];

            for (int i = 0; i < 4; i++)
            {
                float h = baseColors[i].H + deltaH;
                float s = baseColors[i].S + deltaS;

                // keep h in [0..360)
                while (h < 0f)
                {
                    h = h + 360f;
                }
                while (h >= 360f)
                {
                    h = h - 360f;
                }

                // clamp s to [0..1]
                if (s > 1f)
                {
                    s = 1f;
                }
                if (s < 0f)
                {
                    s = 0f;
                }

                retColors[i] = new HSVColor(h, s, baseColors[i].V);
            }
            return retColors;
        }
コード例 #21
0
 public HSVColor ClosestColor(HSVColor color)
 {
     int index = ClosestIndex(color);
     return new HSVColor(centers[index], color.V);
 }
コード例 #22
0
        private void colorToLibraryButton_Click(object sender, EventArgs e)
        {
            HSVColor [] colors = new HSVColor[4];
            colors[0] = AdjustedColor(0);
            colors[1] = AdjustedColor(1);
            colors[2] = AdjustedColor(2);
            colors[3] = AdjustedColor(3);

            string tilename;
            string colorname;

            TreeNode selectedNode = libraryTreeView.SelectedNode;
            if (selectedNode.Tag != null)
            {
                colorname = selectedNode.Text;
                tilename = selectedNode.Parent.Text;
            }
            else
            {
                tilename = Path.GetFileNameWithoutExtension(currentTileName);
                colorname = "";
            }

            using (TileColorPrompt dlg = new TileColorPrompt())
            {
                dlg.TileName = tilename;
                dlg.ColorName = colorname;
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    tilename = dlg.TileName;
                    colorname = dlg.ColorName;

                    library.AddEntry(tilename, colorname, colors);

                    LibraryToTreeview();
                }
            }
        }
コード例 #23
0
        public int ClosestIndex(HSVColor color)
        {
            float distance;
            float minDist;
            int minIndex;

            minDist = lastCenters[0].Distance(color.HSCartesian);
            minIndex = 0;

            for (int i = 1; i < k; i++)
            {
                distance = lastCenters[i].Distance(color.HSCartesian);
                if (distance < minDist)
                {
                    minDist = distance;
                    minIndex = i;
                }
            }

            return minIndex;
        }
コード例 #24
0
        /// <summary>
        /// computes the distance in cartesian space between the HS components of
        ///   two colors.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public float Distance(HSVColor other)
        {
            float hrad = h * (float)Math.PI / 180.0f;

            float x1 = s * (float)Math.Cos(hrad);
            float y1 = s * (float)Math.Sin(hrad);

            hrad = other.h * (float)Math.PI / 180.0f;

            float x2 = other.s * (float)Math.Cos(hrad);
            float y2 = other.s * (float)Math.Sin(hrad);

            float xdelta = x2 - x1;
            float ydelta = y2 - y1;

            return (float)Math.Sqrt(xdelta * xdelta + ydelta * ydelta);
        }
コード例 #25
0
        public float[] DistanceToCenters(HSVColor color)
        {
            float[] ret = new float[centers.Length];
            Point p = color.HSCartesian;
            for (int i = 0; i < centers.Length; i++)
            {
                ret[i] = centers[i].Distance(p);
            }

            return ret;
        }