ColorDictionaryToPalette <T, K>(List <ConcurrentDictionary <Int32, int> > pals, int palSize) where T : ColorPaletteDisguise, new() where K : ColorPaletteIndex, new() { T[] Palettes = new T[pals.Count]; byte[] cols; int it = 0; int ind = 0; foreach (var p in pals) { Palettes[it] = ColorPaletteDisguise.Generate <T>(ColorPaletteIndex.Generate <K>(it, (palSize + 1) * it), (palSize + 1)); cols = new byte[(palSize + 1) * 4]; cols[0] = 0; cols[1] = 0; cols[2] = 0; cols[3] = 0; ind = 4; foreach (var kvp in p) { cols[ind] = (byte)((kvp.Key >> 24) & 0x000000FF); cols[ind + 1] = (byte)((kvp.Key >> 16) & 0x000000FF); cols[ind + 2] = (byte)((kvp.Key >> 8) & 0x000000FF); cols[ind + 3] = (byte)(kvp.Key & 0x000000FF); ind += 4; } Palettes[it].RealObject.Load(cols); it++; } return(Palettes); }
public static T ReduceColorsFromBitmap <T, K>(int maxSize, Int32[,] bp) where T : ColorPaletteDisguise, new() where K : ColorPaletteIndex, new() { ConcurrentDictionary <int, int> cols = ExtractColors(bp); List <ColorGroup> clsgrs = new List <ColorGroup>(); foreach (var kvp in cols) { clsgrs.Add(new ColorGroup(kvp.Key, kvp.Value)); } clsgrs = HierarchicalClusteringSolver <ColorGroup, ColorReductionClusterNode> .Solve(clsgrs, 100); IntervalHeap <ColorGroup> ih = new IntervalHeap <ColorGroup>(); ih.Add(clsgrs[0]); ColorGroup aux = null; List <ColorGroup> ret = new List <ColorGroup>(); while (ih.Count + ret.Count < maxSize) { aux = ih.DeleteMax(); if (aux.LeftSon != null && aux.RightSon != null) { ih.Add(aux.LeftSon); ih.Add(aux.RightSon); } else { ret.Add(aux); } } foreach (var cg in ih) { ret.Add(cg); } Int32[] Bits = new Int32[bp.GetLength(0) * bp.GetLength(1)]; GCHandle BitsHandle = GCHandle.Alloc(Bits, GCHandleType.Pinned); Bitmap bitm = new Bitmap(bp.GetLength(0), bp.GetLength(1), bp.GetLength(0) * 4, PixelFormat.Format32bppArgb, BitsHandle.AddrOfPinnedObject()); Parallel.For(0, bp.GetLength(0), x => { Parallel.For(0, bp.GetLength(1), y => { ColorGroup cg = new ColorGroup(bp[x, y], 1); int mind = int.MaxValue; ColorGroup minval = null; int curd = 0; foreach (var c in ret) { curd = c.Distance(cg); if (curd < mind) { mind = curd; minval = c; } } Bits[x + (y * bp.GetLength(1))] = (minval.A << 24) + (minval.R << 16) + (minval.G << 8) + (minval.B); }); }); bitm.Save("Try.png"); T res = ColorPaletteDisguise.Generate <T>(ColorPaletteIndex.Generate <K>(0, 0), maxSize + 1); byte[] newcols = new byte[(maxSize + 1) * 4]; int i = 4; foreach (var c in ret) { newcols[i] = (byte)c.A; newcols[i + 1] = (byte)c.R; newcols[i + 2] = (byte)c.G; newcols[i + 3] = (byte)c.B; i += 4; } res.RealObject.Load(newcols); return(res); }