public void CalculatePalette(int colorCount = 256) { if (colorCount > 256) { colorCount = 256; // For some reason it fails with more... } var colorThief = new ColorThief(); var palette = new List <QuantizedColor>(); using (var image = ToBitmap()) palette = colorThief.GetPalette(image, colorCount, 10, false); // Sort colours by YIQ luma so they align nicely var sortedPalette = palette.OrderBy(entry => entry.CalculateYiqLuma(entry.Color)); Palette.Clear(); foreach (var color in sortedPalette) { if (color.Color.ToHsl().L > 0.009) // Filter out dark values { var newColor = new ColorC(color.Color.R, color.Color.G, color.Color.B); if (!Palette.Contains(newColor)) // Filter out duplicates { Palette.Add(newColor); } } } }
public static DiscordColor Analyze(byte[] jpg, DiscordColor defaultColor) { try { // when running dotnet from the snap, it will segfault on attempt to create a Bitmap if (SandboxDetector.Detect() == SandboxType.Snap) { return(defaultColor); } var analyzer = new ColorThief(); using var stream = new MemoryStream(jpg); var bmp = new Bitmap(stream, false); var palette = analyzer.GetPalette(bmp, 4, ignoreWhite: false); var colors = palette .Select(p => new { c = p.Color, hsl = p.Color.ToHsl() }) .OrderBy(p => Math.Abs(0.75 - p.hsl.L)) .ThenByDescending(p => p.hsl.S) .ToList(); #if DEBUG Config.Log.Trace("Selected palette:"); foreach (var cl in colors) { Config.Log.Trace($"{cl.c.ToHexString()}, HSL: {cl.hsl.H+90:#00} {cl.hsl.S:0.00} {cl.hsl.L:0.00}"); } #endif var c = colors[0].c; return(new DiscordColor(c.R, c.G, c.B)); } catch (Exception e) { Config.Log.Warn(e, "Failed to extract image palette"); return(defaultColor); } }
private static List <QuantizedColor> GetDominantColors(DominantColorAttribute dominantColorAttribute, ImageData image) { using (var bitmap = new Bitmap(image.BinaryData.OpenRead())) { var colorThief = new ColorThief(); var palette = colorThief.GetPalette(bitmap, dominantColorAttribute?.PaletteColorCount ?? 5, dominantColorAttribute?.Quality ?? 10, dominantColorAttribute?.Ignorewhite ?? true); if (!palette.Any()) { palette.Add(colorThief.GetColor(bitmap, dominantColorAttribute?.Quality ?? 10, dominantColorAttribute?.Ignorewhite ?? true)); } return(palette); } }
/// <summary> /// Applies image segmentation on an image to get the amount of specified colors from the image. /// </summary> /// <param name="colorCount">The color count.</param> /// <param name="quality">The quality.</param> public async Task ApplyImageSegmentation(int colorCount, int quality) { var colorThief = new ColorThief(); var fileStream = await this.sourcePicture.File.OpenAsync(FileAccessMode.Read); var decoder = await BitmapDecoder.CreateAsync(fileStream); var colors = await colorThief.GetPalette(decoder, colorCount, quality, false); for (var i = 0; i < this.sourcePicture.Width - 1; i++) { for (var j = 0; j < this.sourcePicture.Height - 1; j++) { var sourcePixelColor = PixelUtilities.GetPixelBgra8(this.sourcePicture.Pixels, j, i, this.sourcePicture.Width, this.sourcePicture.Height); this.setPixelToClosestQuantizedColor(colors, sourcePixelColor, MaxDistance, j, i); } } this.sourcePicture.ModifiedImage = new WriteableBitmap((int)this.sourcePicture.Width, (int)this.sourcePicture.Height); }
/// <summary> /// Get a color palette based on the image given. /// <paramref name="albumArt"/> Bitmap of the image</param> /// <paramref name="paletteSize"/> Amount of different colors. eg. Color palette size of 8 = 8 colors</param> /// <paramref name="resizeFactor"/> Resize image factor. eg resize factor 50 sizes image down by half</param> /// </summary> public List <string> getColorPalette(Bitmap albumArt, int paletteSize, int resizeFactor) { List <string> colorMajorities = new List <string>(); if (albumArt == null) { return(new List <string> { "FFFFFF" }); } using (var resizedArt = ResizeBitmap(albumArt, albumArt.Width * (resizeFactor / 100), albumArt.Height * (resizeFactor / 100))) { var colorThief = new ColorThief(); var palette = colorThief.GetPalette(resizedArt, paletteSize).ToList(); foreach (QuantizedColor i in palette) { colorMajorities.Add(i.Color.R.ToString("X2") + i.Color.G.ToString("X2") + i.Color.B.ToString("X2")); } } return(colorMajorities); }
private static Color DetectBestColor(Bitmap bmp) { var colorThief = new ColorThief(); var colors = colorThief.GetPalette(bmp, 8); var pluginColors = new List <PluginColor>(); var maxPopulation = (from pluginColor in colors select pluginColor.Population).Max(); foreach (var color in colors) { var col = ColorTranslator.FromHtml(color.Color.ToHexString()); var populationWeight = 0.5; var saturationWeight = (float)Math.Tanh(col.GetSaturation()); double darkWeight; var populationPercent = (double)color.Population / maxPopulation; if (populationPercent > 0.3) { populationWeight = 0.3; } if (populationPercent < 0.1 && populationPercent > 0.01) { populationWeight = 0.8; } if (populationPercent <= 0.01) { populationWeight = 0.2; } if (color.IsDark) { darkWeight = 1; } else { darkWeight = 0.3; } if (col.GetBrightness() > 0.5) { darkWeight = 0; } var weight = populationWeight + darkWeight + saturationWeight; pluginColors.Add(new PluginColor { ColorCode = color.Color.ToHexString(), Weight = weight }); } var orderedColors = (from pluginColor in pluginColors orderby pluginColor.Weight descending select pluginColor).ToList(); var bestColor = orderedColors.FirstOrDefault(); var resultColor = NiResourceColor.GetRandomColor(); if (bestColor == null) { return(resultColor); } var colorCode = bestColor.ColorCode; var convertedColor = ColorConverter.ConvertFromString(colorCode); if (convertedColor != null) { resultColor = (Color)convertedColor; } return(resultColor); }
public async Task <List <QuantizedColor> > GetPalette(ImageSource sourceImage, int colorCount = ColorThief.DefaultColorCount, int quality = ColorThief.DefaultQuality, bool ignoreWhite = ColorThief.DefaultIgnoreWhite) { return(await ct.GetPalette(await GetImageFromImageSource(sourceImage), colorCount, quality, ignoreWhite)); }
/// <summary> /// Analyses a <see cref="Stream"/> of an image into a color palette. /// </summary> /// <param name="str">Image stream.</param> /// <param name="width">Width of the image.</param> /// <param name="height">Height of the image.</param> public async void Analyse(Stream str, int width = 96, int height = 66) { WriteableBitmap wbm = new WriteableBitmap(width, height); await wbm.SetSourceAsync(str.AsRandomAccessStream()); str.Dispose(); Debug.WriteLine(DateTime.Now + "GOT IMAGE"); List <MMCQ.QuantizedColor> palette1 = ColorThief.GetPalette(wbm, 12, 4, true); List <MMCQ.QuantizedColor> palette2 = new List <MMCQ.QuantizedColor>(); List <MMCQ.QuantizedColor> palette3 = new List <MMCQ.QuantizedColor>(); foreach (var v in palette1) { var hsl = FromRGB(v.Color.R, v.Color.G, v.Color.B); v.hsl = new MMCQ.HSLColor((float)Math.Round(hsl.H, 3), (float)Math.Round(hsl.S, 3), (float)Math.Round(hsl.L, 3)); if (hsl.L > 0.35) { palette2.Add(v); } } palette2 = palette2.OrderBy(x => x.hsl.S).Reverse().ToList(); if (palette2.Count > 6) { palette2.RemoveRange(6, palette2.Count - 6); } ColorList = palette2; palette3.Add(palette2.First()); palette3.Add(palette2.Last()); var color = palette2.First(); var color2 = palette2.ElementAt(1); palette3.Add(palette2.First()); foreach (var c in palette2) { Debug.WriteLine("HSL.S (" + c.hsl.S + ") > 0.1"); var dif1 = Math.Abs(color.hsl.H - color2.hsl.H); var dif2 = Math.Abs(color.hsl.H - c.hsl.H); if (dif2 > dif1 && c.hsl.S > 0.1) { color2 = c; } } if (color2.hsl.L > color.hsl.L) { var dif = Math.Abs(color.hsl.L - color2.hsl.L); if (dif > 0.2) { var altcolor = color; color = color2; color2 = altcolor; } } color.name = "Accent"; color2.name = "Secondary"; Color newcolor2 = color2.Color; if (color2.hsl.L < 0.5) { newcolor2 = Color.FromArgb(255, Convert.ToByte(color2.Color.R + 15), Convert.ToByte(color2.Color.G + 15), Convert.ToByte(color2.Color.B + 15)); } Debug.WriteLine("Accent color HSL.L = " + color.hsl.L.ToString()); Debug.WriteLine("Accent color HSL.S = " + color.hsl.S.ToString()); Debug.WriteLine("Secondary color HSL.L = " + color2.hsl.L.ToString()); Debug.WriteLine("Secondary color HSL.S = " + color2.hsl.S.ToString()); }
public void Image3() { var colorThief = new ColorThief(); var bitmap = (Bitmap)Image.FromFile("test3.jpg"); var result = colorThief.GetPalette(bitmap, 5, 1, true).OrderByDescending(a => a.Population); }
/// <summary> /// Extract color palette from image /// </summary> /// <param name="wallpaper"></param> public void ExtractColors(Models.Wallpaper.Entities.Wallpaper wallpaper) { new Thread(() => { Thread.CurrentThread.IsBackground = true; // wallpaper image var image = new BitmapImage(new Uri(wallpaper.Path)); // copy to byte array int stride = image.PixelWidth * 4; byte[] buffer = new byte[stride * image.PixelHeight]; image.CopyPixels(buffer, stride, 0); // create bitmap System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap( image.PixelWidth, image.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); // lock bitmap data System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits( new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bitmap.PixelFormat); // copy byte array to bitmap data System.Runtime.InteropServices.Marshal.Copy( buffer, 0, bitmapData.Scan0, buffer.Length); // unlock bitmap.UnlockBits(bitmapData); // extract colors var colorThief = new ColorThief(); var palette = colorThief.GetPalette(bitmap, 5, 7); if (palette.Count > 0) { foreach (var item in palette) { var color = new Models.Wallpaper.Entities.Color { WallpaperId = wallpaper.Id, ColorCode = item.Color.ToHexString() }; wallpaper.ColorPalette.Add(color); } if (wallpaper.ColorPalette.Count > 0) { using var db = new AppDbContext(); db.Colors.AddRange(wallpaper.ColorPalette); db.SaveChanges(); } } }).Start(); }