예제 #1
0
            private static int GetMask(WuPixel[] palette)
            {
                IEnumerable <byte> alphas = from pixel in palette
                                            select pixel.Alpha;
                byte maxAlpha     = alphas.Max();
                int  uniqueAlphas = alphas.Distinct().Count();

                IEnumerable <byte> reds = from pixel in palette
                                          select pixel.Red;
                byte maxRed     = reds.Max();
                int  uniqueReds = reds.Distinct().Count();

                IEnumerable <byte> greens = from pixel in palette
                                            select pixel.Green;
                byte maxGreen     = greens.Max();
                int  uniqueGreens = greens.Distinct().Count();

                IEnumerable <byte> blues = from pixel in palette
                                           select pixel.Blue;
                byte maxBlue     = blues.Max();
                int  uniqueBlues = blues.Distinct().Count();

                double totalUniques = uniqueAlphas + uniqueReds + uniqueGreens + uniqueBlues;

                double AvailableBits = 1.0 + Math.Log(uniqueAlphas * uniqueReds * uniqueGreens * uniqueBlues);

                byte alphaMask = ComputeBitMask(maxAlpha, Convert.ToInt32(Math.Round(uniqueAlphas / totalUniques * AvailableBits)));
                byte redMask   = ComputeBitMask(maxRed, Convert.ToInt32(Math.Round(uniqueReds / totalUniques * AvailableBits)));
                byte greenMask = ComputeBitMask(maxGreen, Convert.ToInt32(Math.Round(uniqueGreens / totalUniques * AvailableBits)));
                byte blueMask  = ComputeBitMask(maxAlpha, Convert.ToInt32(Math.Round(uniqueBlues / totalUniques * AvailableBits)));

                WuPixel maskedPixel = new WuPixel(alphaMask, redMask, greenMask, blueMask);

                return(maskedPixel.Argb);
            }
예제 #2
0
 public void AddPixel(WuPixel pixel)
 {
     Alpha += pixel.Alpha;
     Red   += pixel.Red;
     Green += pixel.Green;
     Blue  += pixel.Blue;
     Sum++;
 }
예제 #3
0
            public void Add(WuPixel p)
            {
                byte pAlpha = p.Alpha;
                byte pRed   = p.Red;
                byte pGreen = p.Green;
                byte pBlue  = p.Blue;

                Alpha += pAlpha;
                Red   += pRed;
                Green += pGreen;
                Blue  += pBlue;
                Weight++;
                Moment += pAlpha * pAlpha + pRed * pRed + pGreen * pGreen + pBlue * pBlue;
            }
예제 #4
0
            public byte GetPaletteIndex(WuPixel pixel)
            {
                int pixelKey = pixel.Argb & mMask;

                LookupNode[] bucket;
                if (!mLookup.TryGetValue(pixelKey, out bucket))
                {
                    bucket = Palette;
                }

                if (bucket.Length == 1)
                {
                    return(bucket[0].PaletteIndex);
                }

                int  bestDistance = int.MaxValue;
                byte bestMatch    = 0;

                foreach (var lookup in bucket)
                {
                    var lookupPixel = lookup.Pixel;

                    var deltaAlpha = pixel.Alpha - lookupPixel.Alpha;
                    int distance   = deltaAlpha * deltaAlpha;

                    var deltaRed = pixel.Red - lookupPixel.Red;
                    distance += deltaRed * deltaRed;

                    var deltaGreen = pixel.Green - lookupPixel.Green;
                    distance += deltaGreen * deltaGreen;

                    var deltaBlue = pixel.Blue - lookupPixel.Blue;
                    distance += deltaBlue * deltaBlue;

                    if (distance >= bestDistance)
                    {
                        continue;
                    }

                    bestDistance = distance;
                    bestMatch    = lookup.PaletteIndex;
                }

                if ((bucket == Palette) && (pixelKey != 0))
                {
                    mLookup[pixelKey] = new LookupNode[] { bucket[bestMatch] };
                }

                return(bestMatch);
            }
예제 #5
0
        private static byte[] IndexedPixels(Color[] pixels, WuPixel[] lookups, int alphaThreshold, int maxColors, PaletteColorHistory[] paletteHistogram)
        {
            var length = maxColors == 256 ? pixels.Length : maxColors == 16 ? pixels.Length / 2 : throw new Exception("IndexedPixels: unknown pixelformat");

            byte[]        returned = new byte[length];
            PaletteLookup lookup   = new PaletteLookup(lookups);

            --maxColors;
            for (int i = 0; i < pixels.Length; i++)
            {
                WuPixel pixel     = new WuPixel(pixels[i].A, pixels[i].R, pixels[i].G, pixels[i].B);
                byte    bestMatch = (byte)maxColors;
                if (pixel.Alpha > alphaThreshold)
                {
                    bestMatch = lookup.GetPaletteIndex(pixel);
                    paletteHistogram[bestMatch].AddPixel(pixel);
                }
                switch (maxColors)
                {
                case 256 - 1:
                    returned[i] = bestMatch;
                    break;

                case 16 - 1:
                    if (i % 2 == 0)
                    {
                        returned[i / 2] = (byte)(bestMatch << 4);
                    }
                    else
                    {
                        returned[i / 2] |= (byte)(bestMatch & 0x0F);
                    }
                    break;

                case 2 - 1:
                    if (i % 8 == 0)
                    {
                        returned[i / 8] = (byte)(bestMatch << 7);
                    }
                    else
                    {
                        returned[i / 8] |= (byte)((bestMatch & 0x01) << (7 - (i % 8)));
                    }
                    break;
                }
            }

            return(returned);
        }
예제 #6
0
        private static WuPixel[] BuildLookups(Box[] cubes, ColorMoment[,,,] moments)
        {
            WuPixel[] lookups = new WuPixel[cubes.Length];

            for (int cubeIndex = 0; cubeIndex < cubes.Length; cubeIndex++)
            {
                var volume = Volume(cubes[cubeIndex], moments);

                if (volume.Weight <= 0)
                {
                    continue;
                }

                var lookup = new WuPixel
                {
                    Alpha = (byte)(volume.Alpha / volume.Weight),
                    Red   = (byte)(volume.Red / volume.Weight),
                    Green = (byte)(volume.Green / volume.Weight),
                    Blue  = (byte)(volume.Blue / volume.Weight)
                };
                lookups[cubeIndex] = lookup;
            }
            return(lookups);
        }