public OctreeNode(int level, OctreeQuantizer parent) //level - level of parent { nodes = new OctreeNode[8]; if (level < 7) { parent.AddLevelNode(level, this); } }
/// <summary> /// Convert the image to gif with 256 colors /// </summary> /// <returns>256 colors gif image</returns> public Bitmap ToGif() { // initialize the color quantizer OctreeQuantizer quantizer = new OctreeQuantizer(); // initialize the 256 colors palette List <Color> limitedPalette = new List <Color>(); // scan the image pixels for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { // get the current color Color c = GetPixel(x, y); // add the color to the quantizer quantizer.AddColor(c); } } // limit the colors to 256 limitedPalette = quantizer.GetPalette(256); // initialize the bitmap memory lock data int stride = 4 * ((Width * 8 + 31) / 32); byte[,] b = new byte[Height, stride]; GCHandle gch = GCHandle.Alloc(b, GCHandleType.Pinned); // create the gif image using (Bitmap quantizedBmp = new Bitmap(Width, Height, stride, PixelFormat.Format8bppIndexed, gch.AddrOfPinnedObject())) { // get the current palette ColorPalette pal = quantizedBmp.Palette; // fill the palette with the correct colors for (int i = 0; i < pal.Entries.Length; i++) { // reset the color pal.Entries[i] = Color.Transparent; // if we have more colors, we add it if (i < limitedPalette.Count) { pal.Entries[i] = limitedPalette[i]; } } // store the palette quantizedBmp.Palette = pal; // scan the image for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { // replace the pixel with the new limited palette color b[y, x] = (byte)Array.FindIndex(quantizedBmp.Palette.Entries, cl => cl == limitedPalette[quantizer.GetPaletteIndex(GetPixel(x, y))]); // prevent the app from freezing Application.DoEvents(); } } // unlock the bitmap gch.Free(); // store the gif for future uses return((Bitmap)quantizedBmp.Clone()); } }