Example #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 void AddPixel(Pixel pixel)
 {
     Alpha += pixel.Alpha;
     Red += pixel.Red;
     Green += pixel.Green;
     Blue += pixel.Blue;
     Sum++;
 }
Example #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;
 }
Example #4
0
        protected override QuantizedPalette GetQuantizedPalette(int colorCount, ColorData data, IEnumerable <Box> cubes, int alphaThreshold)
        {
            int        imageSize = data.PixelsCount;
            LookupData lookups   = BuildLookups(cubes, data);

            IList <int> quantizedPixels = data.QuantizedPixels;

            for (var index = 0; index < imageSize; ++index)
            {
                var indexParts = BitConverter.GetBytes(quantizedPixels[index]);
                quantizedPixels[index] = lookups.Tags[indexParts[Alpha], indexParts[Red], indexParts[Green], indexParts[Blue]];
            }

            var alphas  = new int[colorCount + 1];
            var reds    = new int[colorCount + 1];
            var greens  = new int[colorCount + 1];
            var blues   = new int[colorCount + 1];
            var sums    = new int[colorCount + 1];
            var palette = new QuantizedPalette(imageSize);

            IList <Pixel>  pixels       = data.Pixels;
            int            pixelsCount  = data.PixelsCount;
            IList <Lookup> lookupsList  = lookups.Lookups;
            int            lookupsCount = lookupsList.Count;

            Dictionary <int, int> cachedMaches = new Dictionary <int, int>();

            for (int pixelIndex = 0; pixelIndex < pixelsCount; pixelIndex++)
            {
                Pixel pixel = pixels[pixelIndex];
                palette.PixelIndex[pixelIndex] = -1;
                if (pixel.Alpha <= alphaThreshold)
                {
                    continue;
                }

                int bestMatch;
                int argb = pixel.Argb;

                if (!cachedMaches.TryGetValue(argb, out bestMatch))
                {
                    int match = quantizedPixels[pixelIndex];
                    bestMatch = match;
                    int bestDistance = int.MaxValue;

                    for (int lookupIndex = 0; lookupIndex < lookupsCount; lookupIndex++)
                    {
                        Lookup lookup     = lookupsList[lookupIndex];
                        var    deltaAlpha = pixel.Alpha - lookup.Alpha;
                        var    deltaRed   = pixel.Red - lookup.Red;
                        var    deltaGreen = pixel.Green - lookup.Green;
                        var    deltaBlue  = pixel.Blue - lookup.Blue;

                        int distance = deltaAlpha * deltaAlpha + deltaRed * deltaRed + deltaGreen * deltaGreen + deltaBlue * deltaBlue;

                        if (distance >= bestDistance)
                        {
                            continue;
                        }

                        bestDistance = distance;
                        bestMatch    = lookupIndex;
                    }

                    cachedMaches[argb] = bestMatch;
                }

                alphas[bestMatch] += pixel.Alpha;
                reds[bestMatch]   += pixel.Red;
                greens[bestMatch] += pixel.Green;
                blues[bestMatch]  += pixel.Blue;
                sums[bestMatch]++;

                palette.PixelIndex[pixelIndex] = bestMatch;
            }

            for (var paletteIndex = 0; paletteIndex < colorCount; paletteIndex++)
            {
                if (sums[paletteIndex] > 0)
                {
                    alphas[paletteIndex] /= sums[paletteIndex];
                    reds[paletteIndex]   /= sums[paletteIndex];
                    greens[paletteIndex] /= sums[paletteIndex];
                    blues[paletteIndex]  /= sums[paletteIndex];
                }

                var color = Color.FromArgb(alphas[paletteIndex], reds[paletteIndex], greens[paletteIndex], blues[paletteIndex]);
                palette.Colors.Add(color);
            }

            palette.Colors.Add(Color.FromArgb(0, 0, 0, 0));

            return(palette);
        }