public ImageIndexer(List<Bitmap> bl, int paletteCount, bool useAlpha, int transpCol) { this.bl = bl; this.paletteCount = paletteCount; this.useAlpha = useAlpha; boxColorCount = bl.Count * 3; //COMPUTE FREQUENCY TABLE freqTable = new Dictionary<MultiColor,int>(); //Quick check just in case... width = bl[0].Width; height = bl[0].Height; foreach(Bitmap b in bl) { if (b.Width != width || b.Height != height) throw new Exception("Not all images have the same size!!"); } for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for(int i = 0; i < bl.Count; i++) c.setColor(i, bl[i].GetPixel(x, y)); c.calcHash(); if(!c.allTransparent()) if (freqTable.ContainsKey(c)) freqTable[c]++; else freqTable[c] = 1; } int ct = 0; foreach (MultiColor c in freqTable.Keys) if (c.someTransparent()) ct++; // Console.Out.WriteLine("Transparent: " + ct); Dictionary<MultiColor, int> newFreqTable = new Dictionary<MultiColor, int>(); foreach (MultiColor c in freqTable.Keys) { if (!c.deleteFlag) { int cnt = freqTable[c]; foreach(MultiColor c2 in freqTable.Keys) { if (c2 == null) continue; if (c2.deleteFlag) continue; if (c2 == c) continue; if (c.diff(c2) == 0) { cnt += freqTable[c2]; c.merge(c2); c2.deleteFlag = true; } } c.deleteFlag = true; c.removeAllTransparent(); newFreqTable.Add(c, cnt); } } freqTable = newFreqTable; ct = 0; foreach (MultiColor c in freqTable.Keys) if (c.someTransparent()) ct++; // Console.Out.WriteLine("Transparent2: " + ct); // NOW CREATE THE PALETTE ZONES Box startBox = shrinkBox(new Box(boxColorCount)); boxes = new List<Box>(); boxes.Add(startBox); while (boxes.Count < (useAlpha ? paletteCount - 1 : paletteCount)) { // Console.Out.WriteLine(boxes.Count); Box bo = getDominantBox(); if (bo == null) break; split(bo); } multiPalette = new MultiColor[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) if ((useAlpha ? j : j + 1) <= boxes.Count) multiPalette[j] = boxes[useAlpha ? j - 1 : j].center(); //NOW CREATE THE PALETTE COLORS palettes = new Color[bl.Count][]; for (int i = 0; i < bl.Count; i++) { palettes[i] = new Color[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) { if ((useAlpha ? j : j + 1) > boxes.Count) palettes[i][j] = Color.Fuchsia; else palettes[i][j] = boxes[useAlpha ? j - 1 : j].center().getColor(i); // Console.Out.WriteLine(i + ": " + boxes[i] + ": "+ palette[i]); } if (useAlpha) palettes[i][0] = Color.Transparent; } //NOW MAP ORIGINAL COLORS TO PALETTE ENTRIES colorTable = new Dictionary<MultiColor, byte>(); foreach (MultiColor c in freqTable.Keys) colorTable[c] = closestMultiColor(c); //NOW INDEX THE WHOLE IMAGES imageData = new byte[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for (int i = 0; i < bl.Count; i++) c.setColor(i, bl[i].GetPixel(x, y)); c.calcHash(); if (c.allTransparent()) imageData[x, y] = (byte)transpCol; else imageData[x, y] = closestMultiColor(c); } } Console.Out.WriteLine("DONE"); /* }*/ }
public ImageIndexer(List <Bitmap> bl, int paletteCount, bool useAlpha, int transpCol) { this.bl = bl; this.paletteCount = paletteCount; this.useAlpha = useAlpha; boxColorCount = bl.Count * 3; //COMPUTE FREQUENCY TABLE freqTable = new Dictionary <MultiColor, int>(); //Quick check just in case... width = bl[0].Width; height = bl[0].Height; foreach (Bitmap b in bl) { if (b.Width != width || b.Height != height) { throw new Exception("Not all images have the same size!!"); } } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for (int i = 0; i < bl.Count; i++) { c.setColor(i, bl[i].GetPixel(x, y)); } c.calcHash(); if (!c.allTransparent()) { if (freqTable.ContainsKey(c)) { freqTable[c]++; } else { freqTable[c] = 1; } } } } int ct = 0; foreach (MultiColor c in freqTable.Keys) { if (c.someTransparent()) { ct++; } } // Console.Out.WriteLine("Transparent: " + ct); Dictionary <MultiColor, int> newFreqTable = new Dictionary <MultiColor, int>(); foreach (MultiColor c in freqTable.Keys) { if (!c.deleteFlag) { int cnt = freqTable[c]; foreach (MultiColor c2 in freqTable.Keys) { if (c2 == null) { continue; } if (c2.deleteFlag) { continue; } if (c2 == c) { continue; } if (c.diff(c2) == 0) { cnt += freqTable[c2]; c.merge(c2); c2.deleteFlag = true; } } c.deleteFlag = true; c.removeAllTransparent(); newFreqTable.Add(c, cnt); } } freqTable = newFreqTable; ct = 0; foreach (MultiColor c in freqTable.Keys) { if (c.someTransparent()) { ct++; } } // Console.Out.WriteLine("Transparent2: " + ct); // NOW CREATE THE PALETTE ZONES Box startBox = shrinkBox(new Box(boxColorCount)); boxes = new List <Box>(); boxes.Add(startBox); while (boxes.Count < (useAlpha ? paletteCount - 1 : paletteCount)) { // Console.Out.WriteLine(boxes.Count); Box bo = getDominantBox(); if (bo == null) { break; } split(bo); } multiPalette = new MultiColor[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) { if ((useAlpha ? j : j + 1) <= boxes.Count) { multiPalette[j] = boxes[useAlpha ? j - 1 : j].center(); } } //NOW CREATE THE PALETTE COLORS palettes = new Color[bl.Count][]; for (int i = 0; i < bl.Count; i++) { palettes[i] = new Color[paletteCount]; for (int j = useAlpha ? 1 : 0; j < paletteCount; j++) { if ((useAlpha ? j : j + 1) > boxes.Count) { palettes[i][j] = Color.Fuchsia; } else { palettes[i][j] = boxes[useAlpha ? j - 1 : j].center().getColor(i); } // Console.Out.WriteLine(i + ": " + boxes[i] + ": "+ palette[i]); } if (useAlpha) { palettes[i][0] = Color.Transparent; } } //NOW MAP ORIGINAL COLORS TO PALETTE ENTRIES colorTable = new Dictionary <MultiColor, byte>(); foreach (MultiColor c in freqTable.Keys) { colorTable[c] = closestMultiColor(c); } //NOW INDEX THE WHOLE IMAGES imageData = new byte[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MultiColor c = new MultiColor(boxColorCount); for (int i = 0; i < bl.Count; i++) { c.setColor(i, bl[i].GetPixel(x, y)); } c.calcHash(); if (c.allTransparent()) { imageData[x, y] = (byte)transpCol; } else { imageData[x, y] = closestMultiColor(c); } } } Console.Out.WriteLine("DONE"); /* * * }*/ }