コード例 #1
0
        public static List <Color> MedianCut(Bitmap bitmap, int count)
        {
            List <List <Color> > colors = new List <List <Color> >()
            {
                BitmapConvert.ColorArrayFromBitmap(bitmap).ToList()
            };

            while (colors.Count * 2 <= count)
            {
                List <List <Color> > nextColors = new List <List <Color> >();
                Parallel.ForEach(colors, pixels => {
                    var splitted = SplitColors(pixels);
                    nextColors.Add(splitted.Item1);
                    nextColors.Add(splitted.Item2);
                });
                colors = nextColors;
            }
            while (colors.Count < count)
            {
                var splitted = SplitColors(colors[colors.Count - 1]);
                colors.RemoveAt(colors.Count - 1);
                colors.Add(splitted.Item1);
                colors.Add(splitted.Item2);
            }
            List <Color> resultColors = new List <Color>();

            foreach (var pixels in colors)
            {
                resultColors.Add(ColorHelpers.AverageColors(pixels));
            }
            return(resultColors);
            //return colors.Select(l => AverageColors(l)).ToList();
        }
コード例 #2
0
        //initialization could be improved
        public static List <Color> KMeans(Bitmap bitmap, int count, int maxSteps)
        {
            Color[] colors   = BitmapConvert.ColorArrayFromBitmap(bitmap);
            int[]   clusters = new int[colors.Length];
            Color[] means    = new Color[count];
            {
                List <Color> sorted = colors.ToList();
                sorted.Sort((a, b) => a.GetHue().CompareTo(b.GetHue()));
                for (int i = 0; i < count; i++)
                {
                    means[i] = sorted[i * (sorted.Count / count) + (sorted.Count / count) / 2];
                }
            }
            bool changed = false;

            for (int step = 0; step < maxSteps; step++)
            {
                Parallel.For(0, colors.Length, i => {
                    int newCluster = ColorHelpers.GetMinDistanceIndex(colors[i], means);
                    if (newCluster != clusters[i])
                    {
                        changed     = true;
                        clusters[i] = newCluster;
                    }
                });
                if (!changed)
                {
                    break;
                }
                int[] clusterCounts = new int[count];
                (int R, int G, int B)[] clusterSums = new (int R, int G, int B)[count];
コード例 #3
0
        public static Bitmap SortColors(Bitmap bitmap, int count)
        {
            DirectBitmap         result = new DirectBitmap(bitmap.Width, bitmap.Height);
            List <List <Color> > colors = new List <List <Color> >()
            {
                BitmapConvert.ColorArrayFromBitmap(bitmap).ToList()
            };

            while (colors.Count * 2 <= count)
            {
                List <List <Color> > nextColors = new List <List <Color> >();
                Parallel.ForEach(colors, pixels => {
                    var splitted = SplitColors(pixels);
                    nextColors.Add(splitted.Item1);
                    nextColors.Add(splitted.Item2);
                });
                colors = nextColors;
            }
            while (colors.Count < count)
            {
                var splitted = PaletteGeneration.SplitColors(colors[colors.Count - 1]);
                colors.RemoveAt(colors.Count - 1);
                colors.Add(splitted.Item1);
                colors.Add(splitted.Item2);
            }
            var resColors = new List <Color>();

            foreach (var pixels in colors)
            {
                resColors.AddRange(pixels);
            }
            int width  = bitmap.Width;
            int height = bitmap.Height;

            Parallel.For(0, bitmap.Width, x => {
                for (int y = 0; y < height; y++)
                {
                    if (y > 0 && y % (height / count) == 0)
                    {
                        result.SetPixel(x, y, Color.Black);
                    }
                    else
                    {
                        result.SetPixel(x, y, resColors[x + y * width]);
                    }
                }
            });
            return(result.Bitmap);
        }
コード例 #4
0
        public static Bitmap ClosestColor(Bitmap bitmap, Color[] colorPalette)
        {
            Color[]      colors = BitmapConvert.ColorArrayFromBitmap(bitmap);
            DirectBitmap result = new DirectBitmap(bitmap.Width, bitmap.Height);
            int          width  = bitmap.Width;
            int          height = bitmap.Height;

            Parallel.For(0, bitmap.Width, x => {
                for (int y = 0; y < height; y++)
                {
                    Color pixel = colors[x + y * width];
                    result.SetPixel(x, y, ColorHelpers.GetMinDistance(pixel, colorPalette));
                    //result.SetPixel(x, y, pixel);
                }
            });
            return(result.Bitmap);
        }
コード例 #5
0
        public static Bitmap ShiftHsl(Bitmap bitmap, float hueShift, float saturation, float lightness)
        {
            Color[]      colors = BitmapConvert.ColorArrayFromBitmap(bitmap);
            DirectBitmap result = new DirectBitmap(bitmap.Width, bitmap.Height);

            for (int x = 0; x < bitmap.Width; x++)
            {
                for (int y = 0; y < bitmap.Height; y++)
                {
                    var hsl = ColorConvertors.ColorToHsl(colors[x + y * bitmap.Width]);
                    hsl.H = MathF.Max(hsl.H + hueShift, 0) % 360;
                    hsl.S = MathF.Min(MathF.Max((hsl.S) * (1 + saturation), 0), 1);
                    hsl.L = MathF.Min(MathF.Max((hsl.L) * (1 + lightness), 0), 1);
                    result.SetPixel(x, y, ColorConvertors.HslToColor(hsl));
                }
            }
            return(result.Bitmap);
        }
コード例 #6
0
        public static Bitmap BlurImage(Bitmap bitmap, float sigma)
        {
            int   range = (int)(1 + sigma * 2f);
            float c     = 1 / MathF.Sqrt(sigma * sigma * 2 * MathF.PI);

            float[] blurMatrix = new float[range];
            for (int i = 0; i < range; i++)
            {
                blurMatrix[i] = MathF.Pow(MathF.E, -(i * i) / (2 * sigma * sigma)) * c;
            }
            Color[]      colors  = BitmapConvert.ColorArrayFromBitmap(bitmap);
            Color[]      colors2 = new Color[colors.Length];
            DirectBitmap result  = new DirectBitmap(bitmap.Width, bitmap.Height);
            int          width   = bitmap.Width;
            int          height  = bitmap.Height;

            Parallel.For(0, bitmap.Width, x => {
                for (int y = 0; y < height; y++)
                {
                    float r = 0;
                    float g = 0;
                    float b = 0;
                    for (int i = x - range + 1; i < x + range; i++)
                    {
                        if (i < 0 || i >= width)
                        {
                            r += colors[x + y * width].R * blurMatrix[Math.Abs(x - i)];
                            g += colors[x + y * width].G * blurMatrix[Math.Abs(x - i)];
                            b += colors[x + y * width].B * blurMatrix[Math.Abs(x - i)];
                        }
                        else
                        {
                            r += colors[i + y * width].R * blurMatrix[Math.Abs(x - i)];
                            g += colors[i + y * width].G * blurMatrix[Math.Abs(x - i)];
                            b += colors[i + y * width].B * blurMatrix[Math.Abs(x - i)];
                        }
                    }
                    colors2[x + y * width] = ColorConvertors.ClampRgbToColor((int)r, (int)g, (int)b);
                }
            });
            Parallel.For(0, bitmap.Height, y => {
                for (int x = 0; x < width; x++)
                {
                    float r = 0;
                    float g = 0;
                    float b = 0;
                    for (int j = y - range + 1; j < y + range; j++)
                    {
                        if (j < 0 || j >= height)
                        {
                            r += colors[x + y * width].R * blurMatrix[Math.Abs(y - j)];
                            g += colors[x + y * width].G * blurMatrix[Math.Abs(y - j)];
                            b += colors[x + y * width].B * blurMatrix[Math.Abs(y - j)];
                        }
                        else
                        {
                            r += colors2[x + j * width].R * blurMatrix[Math.Abs(y - j)];
                            g += colors2[x + j * width].G * blurMatrix[Math.Abs(y - j)];
                            b += colors2[x + j * width].B * blurMatrix[Math.Abs(y - j)];
                        }
                    }
                    result.SetPixel(x, y, ColorConvertors.ClampRgbToColor((int)r, (int)g, (int)b));
                }
            });
            return(result.Bitmap);
        }