Пример #1
0
        private static byte[] GetReducedBitmapKAverage(byte[] source, int width, int height, int k)
        {
            if (source == null)
            {
                throw new Exception("Source Bitmap is null");
            }


            if (k <= 0)
            {
                throw new Exception("K  musi być większe od 0");
            }



            Color[] means = new Color[k];
            double[,] nextMeans = new double[k, 5];
            //array for calcualtio of next mean
            //[k,0]=A of color, [k,1]=R of color, [k,2]=G of color, [k,3]=B of color,
            //[k,4]=count of colors nearest to previous mean
            RSTColorTree tree = new RSTColorTree();

            for (int i = 0; i < k; i++)
            {
                means[i] = GetRandomColor();
            }
            bool changed        = true;
            int  iterationCount = 0;

            while (changed && iterationCount < 1e4) //if iteration bugger than 10000 stop
            {
                changed = false;
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        Color  color    = source.GetPixelFromByteArray(j, i, width);
                        double minDist  = color.GetDistanceBeetweenColors(means[0]);
                        int    minIndex = 0;
                        for (int c = 1; c < k; c++)
                        {
                            double dist = color.GetDistanceBeetweenColors(means[c]);
                            if (dist < minDist)
                            {
                                minDist  = dist;
                                minIndex = c;
                            }
                        }

                        tree.Insert(color, means[minIndex]);
                        nextMeans[minIndex, 0] += color.A;
                        nextMeans[minIndex, 1] += color.R;
                        nextMeans[minIndex, 2] += color.G;
                        nextMeans[minIndex, 3] += color.B;
                        nextMeans[minIndex, 4]++; //increase number of colors
                    }
                }

                for (int index = 0; index < k; index++)
                {
                    if (nextMeans[index, 4] > 0)
                    {
                        byte  A   = (byte)(nextMeans[index, 0] / nextMeans[index, 4]);
                        byte  R   = (byte)(nextMeans[index, 1] / nextMeans[index, 4]);
                        byte  G   = (byte)(nextMeans[index, 2] / nextMeans[index, 4]);
                        byte  B   = (byte)(nextMeans[index, 3] / nextMeans[index, 4]);
                        Color tmp = Color.FromArgb(A, R, G, B);
                        if (tmp != means[index])
                        {
                            means[index] = tmp;
                            changed      = true;
                        }
                    }
                }
                iterationCount++;
            }

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Color c = source.GetPixelFromByteArray(j, i, width);
                    source.SetPixelInByteArray(j, i, width, tree.GetNewColor(c));//fill source with new colors
                }
            }

            return(source);
        }
Пример #2
0
        private static byte[] GetReducedBitmapKPopular(byte[] source, int width, int height, int k)
        {
            if (source == null)
            {
                throw new Exception("Source Bitmap is null");
            }

            if (k <= 0)
            {
                throw new Exception("K musi być większe od 0");
            }

            RSTColorTree tree = new RSTColorTree();

            Node[] popularColors = new Node[k];

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Color color = source.GetPixelFromByteArray(j, i, width);
                    Node  node  = tree.Insert(color);
                    if (popularColors.FirstOrDefault(c => c == node) != null)
                    {
                        break;
                    }

                    for (int index = 0; index < k; index++)
                    {
                        if (popularColors[index] == null)
                        {
                            popularColors[index] = node;
                            break;
                        }
                        else if (popularColors[index].counter < node.counter)
                        {
                            for (int index2 = k - 1; index2 > index; index2--)
                            {
                                popularColors[index2] = popularColors[index2 - 1];
                            }
                            popularColors[index] = node;
                            break;
                        }
                    }
                }
            }



            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Color  color    = source.GetPixelFromByteArray(j, i, width);
                    double minDist  = color.GetDistanceBeetweenColors(popularColors[0].Value);
                    int    minIndex = 0;
                    for (int index = 0; index < k; index++)
                    {
                        if (popularColors[index] != null)
                        {
                            double dist = color.GetDistanceBeetweenColors(popularColors[index].Value);
                            if (dist < minDist)
                            {
                                minIndex = index;
                                minDist  = dist;
                            }
                        }
                    }
                    source.SetPixelInByteArray(j, i, width, popularColors[minIndex].Value);
                }
            }


            return(source);
        }