//tiles = 16 means 16 x 16 atlas public List <Bitmap> Atlas2dInto1d(Bitmap atlas2d, int tiles, int atlassizezlimit) { IFastBitmap orig = d_FastBitmapFactory(); orig.bmp = atlas2d; int tilesize = atlas2d.Width / tiles; int atlasescount = Math.Max(1, (tiles * tiles * tilesize) / atlassizezlimit); List <Bitmap> atlases = new List <Bitmap>(); orig.Lock(); //256 x 1 IFastBitmap atlas1d = null; for (int i = 0; i < tiles * tiles; i++) { int x = i % tiles; int y = i / tiles; int tilesinatlas = (tiles * tiles / atlasescount); if (i % tilesinatlas == 0) { if (atlas1d != null) { atlas1d.Unlock(); atlases.Add(atlas1d.bmp); } atlas1d = d_FastBitmapFactory(); atlas1d.bmp = new Bitmap(tilesize, atlassizezlimit); atlas1d.Lock(); } for (int xx = 0; xx < tilesize; xx++) { for (int yy = 0; yy < tilesize; yy++) { int c = orig.GetPixel(x * tilesize + xx, y * tilesize + yy); atlas1d.SetPixel(xx, (i % tilesinatlas) * tilesize + yy, c); } } } atlas1d.Unlock(); atlases.Add(atlas1d.bmp); orig.Unlock(); return(atlases); }
public override bool ProcessCapture(ISurface surface, ICaptureDetails captureDetails) { LOG.DebugFormat("Changing surface to grayscale!"); using (IFastBitmap bbb = FastBitmap.Create(surface.Image as Bitmap)) { bbb.Lock(); for (int y = 0; y < bbb.Height; y++) { for (int x = 0; x < bbb.Width; x++) { Color color = bbb.GetColorAt(x, y); int luma = (int)((0.3 * color.R) + (0.59 * color.G) + (0.11 * color.B)); color = Color.FromArgb(luma, luma, luma); bbb.SetColorAt(x, y, color); } } } return(true); }
/// <summary> /// Reindex the 24/32 BPP (A)RGB image to a 8BPP /// </summary> /// <returns>Bitmap</returns> public Bitmap SimpleReindex() { List <Color> colors = new List <Color>(); Dictionary <Color, byte> lookup = new Dictionary <Color, byte>(); using (FastChunkyBitmap bbbDest = FastBitmap.Create(resultBitmap) as FastChunkyBitmap) { bbbDest.Lock(); using (IFastBitmap bbbSrc = FastBitmap.Create(sourceBitmap)) { IFastBitmapWithBlend bbbSrcBlend = bbbSrc as IFastBitmapWithBlend; bbbSrc.Lock(); byte index; for (int y = 0; y < bbbSrc.Height; y++) { for (int x = 0; x < bbbSrc.Width; x++) { Color color; if (bbbSrcBlend != null) { color = bbbSrcBlend.GetBlendedColorAt(x, y); } else { color = bbbSrc.GetColorAt(x, y); } if (lookup.ContainsKey(color)) { index = lookup[color]; } else { colors.Add(color); index = (byte)(colors.Count - 1); lookup.Add(color, index); } bbbDest.SetColorIndexAt(x, y, index); } } } } // generates palette ColorPalette imagePalette = resultBitmap.Palette; Color[] entries = imagePalette.Entries; for (Int32 paletteIndex = 0; paletteIndex < 256; paletteIndex++) { if (paletteIndex < colorCount) { entries[paletteIndex] = colors[paletteIndex]; } else { entries[paletteIndex] = Color.Black; } } resultBitmap.Palette = imagePalette; // Make sure the bitmap is not disposed, as we return it. Bitmap tmpBitmap = resultBitmap; resultBitmap = null; return(tmpBitmap); }
/// <summary> /// See <see cref="IColorQuantizer.Prepare"/> for more details. /// </summary> public WuQuantizer(Bitmap sourceBitmap) { this.sourceBitmap = sourceBitmap; // Make sure the color count variables are reset BitArray bitArray = new BitArray((int)Math.Pow(2, 24)); colorCount = 0; // creates all the cubes cubes = new WuColorCube[MAXCOLOR]; // initializes all the cubes for (Int32 cubeIndex = 0; cubeIndex < MAXCOLOR; cubeIndex++) { cubes[cubeIndex] = new WuColorCube(); } // resets the reference minimums cubes[0].RedMinimum = 0; cubes[0].GreenMinimum = 0; cubes[0].BlueMinimum = 0; // resets the reference maximums cubes[0].RedMaximum = MAXSIDEINDEX; cubes[0].GreenMaximum = MAXSIDEINDEX; cubes[0].BlueMaximum = MAXSIDEINDEX; weights = new Int64[SIDESIZE, SIDESIZE, SIDESIZE]; momentsRed = new Int64[SIDESIZE, SIDESIZE, SIDESIZE]; momentsGreen = new Int64[SIDESIZE, SIDESIZE, SIDESIZE]; momentsBlue = new Int64[SIDESIZE, SIDESIZE, SIDESIZE]; moments = new Single[SIDESIZE, SIDESIZE, SIDESIZE]; Int32[] table = new Int32[256]; for (Int32 tableIndex = 0; tableIndex < 256; ++tableIndex) { table[tableIndex] = tableIndex * tableIndex; } // Use a bitmap to store the initial match, which is just as good as an array and saves us 2x the storage using (IFastBitmap sourceFastBitmap = FastBitmap.Create(sourceBitmap)) { IFastBitmapWithBlend sourceFastBitmapWithBlend = sourceFastBitmap as IFastBitmapWithBlend; sourceFastBitmap.Lock(); using (FastChunkyBitmap destinationFastBitmap = FastBitmap.CreateEmpty(sourceBitmap.Size, PixelFormat.Format8bppIndexed, Color.White) as FastChunkyBitmap) { destinationFastBitmap.Lock(); for (int y = 0; y < sourceFastBitmap.Height; y++) { for (int x = 0; x < sourceFastBitmap.Width; x++) { Color color; if (sourceFastBitmapWithBlend == null) { color = sourceFastBitmap.GetColorAt(x, y); } else { color = sourceFastBitmapWithBlend.GetBlendedColorAt(x, y); } // To count the colors int index = color.ToArgb() & 0x00ffffff; // Check if we already have this color if (!bitArray.Get(index)) { // If not, add 1 to the single colors colorCount++; bitArray.Set(index, true); } Int32 indexRed = (color.R >> 3) + 1; Int32 indexGreen = (color.G >> 3) + 1; Int32 indexBlue = (color.B >> 3) + 1; weights[indexRed, indexGreen, indexBlue]++; momentsRed[indexRed, indexGreen, indexBlue] += color.R; momentsGreen[indexRed, indexGreen, indexBlue] += color.G; momentsBlue[indexRed, indexGreen, indexBlue] += color.B; moments[indexRed, indexGreen, indexBlue] += table[color.R] + table[color.G] + table[color.B]; // Store the initial "match" Int32 paletteIndex = (indexRed << 10) + (indexRed << 6) + indexRed + (indexGreen << 5) + indexGreen + indexBlue; destinationFastBitmap.SetColorIndexAt(x, y, (byte)(paletteIndex & 0xff)); } } resultBitmap = destinationFastBitmap.UnlockAndReturnBitmap(); } } }