public Image QuantizeImage(Bitmap image, int alphaThreshold, int alphaFader, int maxColorCount) { MaxColor = maxColorCount; int colorCount = maxColorCount; ColorData moments = QuantizerBase.CalculateMoments(QuantizerBase.BuildHistogram(image, alphaThreshold, alphaFader)); IEnumerable<Box> cubes = this.SplitData(ref colorCount, moments); QuantizedPalette quantizedPalette = this.GetQuantizedPalette(colorCount, moments, cubes, alphaThreshold); return (Image)QuantizerBase.ProcessImagePixels((Image)image, quantizedPalette); }
private static Bitmap ProcessImagePixels(Image sourceImage, QuantizedPalette palette) { Bitmap bitmap = new Bitmap(sourceImage.Width, sourceImage.Height, PixelFormat.Format8bppIndexed); ColorPalette palette1 = bitmap.Palette; for (int index = 0; index < palette.Colors.Count; ++index) { palette1.Entries[index] = palette.Colors[index]; } bitmap.Palette = palette1; BitmapData bitmapdata = (BitmapData)null; try { bitmapdata = bitmap.LockBits(Rectangle.FromLTRB(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); int num1 = bitmapdata.Stride < 0 ? -bitmapdata.Stride : bitmapdata.Stride; int length1 = Math.Max(1, 1); int length2 = num1 * bitmap.Height; int num2 = 0; byte[] source = new byte[length2]; byte[] numArray = new byte[length1]; int index1 = 0; for (int index2 = 0; index2 < bitmap.Height; ++index2) { int num3 = 0; for (int index3 = 0; index3 < bitmap.Width; ++index3) { int num4 = num3 >> 3; numArray[0] = palette.PixelIndex[index1] == -1 ? (byte)(palette.Colors.Count - 1) : (byte)palette.PixelIndex[index1]; ++index1; for (int index4 = 0; index4 < length1; ++index4) { source[num2 + index4 + num4] = numArray[index4]; } num3 += 8; } num2 += num1; } Marshal.Copy(source, 0, bitmapdata.Scan0, length2); } finally { if (bitmapdata != null) { bitmap.UnlockBits(bitmapdata); } } return(bitmap); }
public Bitmap QuantizeImage(Bitmap image, int alphaThreshold, int alphaFader, int maxColorCount) { if (image.PixelFormat != PixelFormat.Format32bppArgb) { image = image.ConvertToFormat32(); } if (Program.DisableQuantization()) { Console.WriteLine("[WARNING] By disabling quantization, only the first 255 unique colors will be taken into account"); return(image); } mMaxColor = maxColorCount + 1; mMaxColor = Math.Min(mMaxColor, 256); int colorCount = mMaxColor; ColorData moments = QuantizerBase.CalculateMoments(QuantizerBase.BuildHistogram(image, alphaThreshold, alphaFader)); IEnumerable <Box> cubes = this.SplitData(ref colorCount, moments); QuantizedPalette quantizedPalette = this.GetQuantizedPalette(colorCount, moments, cubes, alphaThreshold); return(ProcessImagePixels((Image)image, quantizedPalette)); }
protected override QuantizedPalette GetQuantizedPalette( int colorCount, ColorData data, IEnumerable <Box> cubes, int alphaThreshold) { int pixelsCount1 = data.PixelsCount; LookupData lookupData = this.BuildLookups(cubes, data); IList <int> quantizedPixels = data.QuantizedPixels; for (int index = 0; index < pixelsCount1; ++index) { byte[] bytes = BitConverter.GetBytes(quantizedPixels[index]); quantizedPixels[index] = lookupData.Tags[(int)bytes[3], (int)bytes[2], (int)bytes[1], (int)bytes[0]]; } int[] numArray1 = new int[colorCount + 1]; int[] numArray2 = new int[colorCount + 1]; int[] numArray3 = new int[colorCount + 1]; int[] numArray4 = new int[colorCount + 1]; int[] numArray5 = new int[colorCount + 1]; QuantizedPalette quantizedPalette = new QuantizedPalette(pixelsCount1); IList <Pixel> pixels = data.Pixels; int pixelsCount2 = data.PixelsCount; IList <Lookup> lookups = lookupData.Lookups; int count = lookups.Count; Dictionary <int, int> dictionary = new Dictionary <int, int>(); for (int index1 = 0; index1 < pixelsCount2; ++index1) { Pixel pixel = pixels[index1]; quantizedPalette.PixelIndex[index1] = -1; if ((int)pixel.Alpha > alphaThreshold) { int argb = pixel.Argb; int index2; if (!dictionary.TryGetValue(argb, out index2)) { index2 = quantizedPixels[index1]; int num1 = int.MaxValue; for (int index3 = 0; index3 < count; ++index3) { Lookup lookup = lookups[index3]; int num2 = (int)pixel.Alpha - lookup.Alpha; int num3 = (int)pixel.Red - lookup.Red; int num4 = (int)pixel.Green - lookup.Green; int num5 = (int)pixel.Blue - lookup.Blue; int num6 = num2 * num2 + num3 * num3 + num4 * num4 + num5 * num5; if (num6 < num1) { num1 = num6; index2 = index3; } } dictionary[argb] = index2; } numArray1[index2] += (int)pixel.Alpha; numArray2[index2] += (int)pixel.Red; numArray3[index2] += (int)pixel.Green; numArray4[index2] += (int)pixel.Blue; ++numArray5[index2]; quantizedPalette.PixelIndex[index1] = index2; } } for (int index = 0; index < colorCount; ++index) { if (numArray5[index] > 0) { numArray1[index] /= numArray5[index]; numArray2[index] /= numArray5[index]; numArray3[index] /= numArray5[index]; numArray4[index] /= numArray5[index]; } if (numArray1[index] >= 0 && numArray2[index] >= 0 && numArray3[index] >= 0 && numArray4[index] >= 0) { Color color = Color.FromArgb(numArray1[index], numArray2[index], numArray3[index], numArray4[index]); quantizedPalette.Colors.Add(color); } } quantizedPalette.Colors.Add(Color.FromArgb(0, 0, 0, 0)); return(quantizedPalette); }