Beispiel #1
0
 private static IEnumerable<byte[]> indexedPixels(ImageBuffer image, Pixel[] lookups, int alphaThreshold, int maxColors, PaletteColorHistory[] paletteHistogram)
 {
     int pixelsCount = image.Image.Width * image.Image.Height;
     var lineIndexes = new byte[(int)System.Math.Ceiling(image.Image.Width / System.Math.Log(256.0, maxColors))];
     PaletteLookup lookup = new PaletteLookup(lookups);
     --maxColors;
     foreach (var pixelLine in image.PixelLines)
     {
         for (int pixelIndex = 0; pixelIndex < pixelLine.Length; pixelIndex++)
         {
             Pixel pixel = pixelLine[pixelIndex];
             byte bestMatch = (byte)maxColors;
             if (pixel.Alpha > alphaThreshold)
             {
                 bestMatch = lookup.GetPaletteIndex(pixel);
                 paletteHistogram[bestMatch].AddPixel(pixel);
             }
             switch (maxColors)
             {
                 case 256 - 1:
                     lineIndexes[pixelIndex] = bestMatch;
                     break;
                 case 16 - 1:
                     if (pixelIndex % 2 == 0) { lineIndexes[pixelIndex / 2] = (byte)(bestMatch << 4); }
                     else { lineIndexes[pixelIndex / 2] |= (byte)(bestMatch & 0x0F); }
                     break;
                 case 2 - 1:
                     if (pixelIndex % 8 == 0) { lineIndexes[pixelIndex / 8] = (byte)(bestMatch << 7); }
                     else { lineIndexes[pixelIndex / 8] |= (byte)((bestMatch & 0x01) << (7 - (pixelIndex % 8))); }
                     break;
             }
         }
         yield return lineIndexes;
     }
 }
 public Image QuantizeImage(Bitmap image, int alphaThreshold = 10, int alphaFader = 70, int maxColors = 256)
 {
     var colorCount = maxColors;
     ImageBuffer buffer = new ImageBuffer(image);
     var moments = BuildHistogram(buffer, alphaThreshold, alphaFader);
     CalculateMoments(moments);
     var cubes = SplitData(ref colorCount, maxColors, moments);
     var lookups = BuildLookups(cubes, moments);
     return GetQuantizedImage(buffer, colorCount, maxColors, lookups, alphaThreshold);
 }
Beispiel #3
0
 internal override Image GetQuantizedImage(ImageBuffer image, int colorCount, int maxColors, Pixel[] lookups, int alphaThreshold)
 {
     PixelFormat pf;
     switch (maxColors)
     {
         case 256: pf = PixelFormat.Format8bppIndexed; break;
         case 16: pf = PixelFormat.Format4bppIndexed; break;
         case 2: pf = PixelFormat.Format1bppIndexed; break;
         default: throw new QuantizationException(string.Format("The target amount of colors is not supported. Requested {0} colors.", maxColors));
     }
     var result = new Bitmap(image.Image.Width, image.Image.Height, pf);
     var resultBuffer = new ImageBuffer(result);
     var paletteHistogram = new PaletteColorHistory[colorCount + 1];
     resultBuffer.UpdatePixelIndexes(indexedPixels(image, lookups, alphaThreshold, maxColors, paletteHistogram));
     result.Palette = BuildPalette(result.Palette, paletteHistogram);
     return result;
 }
 internal abstract Image GetQuantizedImage(ImageBuffer image, int colorCount, int maxColors, Pixel[] lookups, int alphaThreshold);
        private static ColorMoment[, , ,] BuildHistogram(ImageBuffer sourceImage, int alphaThreshold, int alphaFader)
        {
            var moments = new ColorMoment[SideSize, SideSize, SideSize, SideSize];
            foreach(var pixelLine in sourceImage.PixelLines)
            {
                for (int pixelIndex = 0; pixelIndex < pixelLine.Length; pixelIndex++)
                {
                    Pixel pixel = pixelLine[pixelIndex];
                    byte pixelAlpha = pixel.Alpha;
                    if (pixelAlpha > alphaThreshold)
                    {
                        if (pixelAlpha < 255)
                        {
                            var alpha = pixel.Alpha + (pixel.Alpha % alphaFader);
                            pixelAlpha = (byte)(alpha > 255 ? 255 : alpha);
                        }
                        byte pixelRed = pixel.Red;
                        byte pixelGreen = pixel.Green;
                        byte pixelBlue = pixel.Blue;

                        pixelAlpha = (byte)((pixelAlpha >> SidePixShift) + 1);
                        pixelRed = (byte)((pixelRed >> SidePixShift) + 1);
                        pixelGreen = (byte)((pixelGreen >> SidePixShift) + 1);
                        pixelBlue = (byte)((pixelBlue >> SidePixShift) + 1);
                        moments[pixelAlpha, pixelRed, pixelGreen, pixelBlue].Add(pixel);
                    }
                }
            }

            return moments;
        }