Ejemplo n.º 1
0
        private IndexedImage CreateNewImageWithPalette(IndexedImage sourceImage, Palette palette, IndexedImage destImage)
        {
            if (destImage == null)
            {
                destImage = sourceImage.Clone(false);
            }
            destImage.Size    = sourceImage.Size;
            destImage.Palette = palette.Clone();

            var destPixels = destImage.Pixels;

            var searcher = new PaletteQuickColorSearcher(palette);

            Parallel.ForEach(sourceImage.Palette,
                             sourceColor =>
            {
                Color substColor = searcher.SearchSubstitute(sourceColor);
                Debug.Assert(substColor != null, "Substitute color was not found.");
                foreach (int occurrence in sourceColor.UsageOccurrences)
                {
                    destPixels[occurrence] = substColor.Argb;
                }
            });

            return(destImage);
        }
        public void TestSearchSubstiture()
        {
            var palette = new Palette
            {
                new Color(0),
                new Color(250, 250, 250),
                new Color(100, 0, 0),
                new Color(0, 100, 0),
                new Color(0, 0, 100),
                new Color(0, 0, 101)
            };

            var quickColorSearcher = new PaletteQuickColorSearcher(palette);

            using (ColorDistance.UseCoeffs(1, 1, 1))
            {
                Assert.AreEqual(new Color(0), quickColorSearcher.SearchSubstitute(new Color(0)));
                Assert.AreEqual(new Color(250, 250, 250), quickColorSearcher.SearchSubstitute(new Color(254, 254, 254)));
                Assert.AreEqual(new Color(0, 0, 100), quickColorSearcher.SearchSubstitute(new Color(98, 98, 99)));
                Assert.AreEqual(new Color(0, 100, 0), quickColorSearcher.SearchSubstitute(new Color(98, 99, 98)));
                Assert.AreEqual(new Color(100, 0, 0), quickColorSearcher.SearchSubstitute(new Color(99, 98, 98)));

                Assert.AreEqual(new Color(0, 0, 100), quickColorSearcher.SearchSubstitute(new Color(0, 0, 99), true));
                Assert.AreEqual(new Color(0, 0, 101), quickColorSearcher.SearchSubstitute(new Color(0, 0, 99), true));
            }
        }
Ejemplo n.º 3
0
        private void UpdateUsagesCounts(Palette palette, IndexedImage sourceImage)
        {
            foreach (Color color in palette)
            {
                color.ClearOccurrences();
            }

            var searcher = new PaletteQuickColorSearcher(palette);

            foreach (Color sourceColor in sourceImage.Palette)
            {
                Color substColor = searcher.SearchSubstitute(sourceColor);
                Debug.Assert(substColor != null, "Substitute color was not found.");
                substColor.OccurrencesCount += sourceColor.OccurrencesCount;
            }
        }
Ejemplo n.º 4
0
        public IndexedImage DitherNewImageWithPalette(IndexedImage sourceImage, Palette palette, int ditherLevel, IndexedImage destImage = null)
        {
            Debug.Assert((ditherLevel >= 1) && (ditherLevel <= MaxDitherLevel), "ditherLevel should is out of range");

            if (destImage == null)
            {
                destImage = sourceImage.Clone(false);
            }
            destImage.Size    = sourceImage.Size;
            destImage.Palette = palette.Clone();

            var sourcePixels = sourceImage.Pixels;
            var destPixels   = destImage.Pixels;

            const int ErrorCoeff = MaxDitherLevel * MaxDitherLevel * 16;

            var tempPixels = new int[sourcePixels.Length, 3];

            for (var i = 0; i < sourcePixels.Length; i++)
            {
                var colorHash = sourcePixels[i];
                tempPixels[i, ColorBytes.RedIdx]   = colorHash.Red() * ErrorCoeff;
                tempPixels[i, ColorBytes.GreenIdx] = colorHash.Green() * ErrorCoeff;
                tempPixels[i, ColorBytes.BlueIdx]  = colorHash.Blue() * ErrorCoeff;
            }

            var ditherLevel2            = ditherLevel * ditherLevel;
            var ditherCoeffRight        = 7 * ditherLevel2;
            var ditherCoeffBottomLeft   = 3 * ditherLevel2;
            var ditherCoeffBottomMiddle = 5 * ditherLevel2;
            var ditherCoeffBottomRight  = 1 * ditherLevel2;

            var searcher = new PaletteQuickColorSearcher(palette);

            var sourceWidth = sourceImage.Size.Width;

            for (var i = 0; i < sourcePixels.Length; i++)
            {
                var r = tempPixels[i, ColorBytes.RedIdx] / ErrorCoeff;
                if (r < 0)
                {
                    r = 0;
                }
                if (r > 255)
                {
                    r = 255;
                }

                var g = tempPixels[i, ColorBytes.GreenIdx] / ErrorCoeff;
                if (g < 0)
                {
                    g = 0;
                }
                if (g > 255)
                {
                    g = 255;
                }

                var b = tempPixels[i, ColorBytes.BlueIdx] / ErrorCoeff;
                if (b < 0)
                {
                    b = 0;
                }
                if (b > 255)
                {
                    b = 255;
                }

                var colorSubs = searcher.SearchSubstitute((byte)r, (byte)g, (byte)b);
                Debug.Assert(colorSubs != null, "Substitute color was not found.");
                destPixels[i] = colorSubs.Argb;

                // Populate errors
                var colorHash = sourcePixels[i];
                var dr        = colorHash.Red() - colorSubs.R;
                var dg        = colorHash.Green() - colorSubs.G;
                var db        = colorHash.Blue() - colorSubs.B;

                var index = i + 1;                 // right
                if ((index < sourcePixels.Length) && ((index % sourceWidth) != 0))
                {
                    tempPixels[index, ColorBytes.RedIdx]   += dr * ditherCoeffRight;
                    tempPixels[index, ColorBytes.GreenIdx] += dg * ditherCoeffRight;
                    tempPixels[index, ColorBytes.BlueIdx]  += db * ditherCoeffRight;
                }

                index = i + sourceWidth - 1;                 // bottom left
                if ((index < sourcePixels.Length) && ((i % sourceWidth) != 0))
                {
                    tempPixels[index, ColorBytes.RedIdx]   += dr * ditherCoeffBottomLeft;
                    tempPixels[index, ColorBytes.GreenIdx] += dg * ditherCoeffBottomLeft;
                    tempPixels[index, ColorBytes.BlueIdx]  += db * ditherCoeffBottomLeft;
                }

                index++;                 // bottom middle
                if (index < sourcePixels.Length)
                {
                    tempPixels[index, ColorBytes.RedIdx]   += dr * ditherCoeffBottomMiddle;
                    tempPixels[index, ColorBytes.GreenIdx] += dg * ditherCoeffBottomMiddle;
                    tempPixels[index, ColorBytes.BlueIdx]  += db * ditherCoeffBottomMiddle;
                }

                index++;                 // bottom right
                if ((index < sourcePixels.Length) && ((index % sourceWidth) != 0))
                {
                    tempPixels[index, ColorBytes.RedIdx]   += dr * ditherCoeffBottomRight;
                    tempPixels[index, ColorBytes.GreenIdx] += dg * ditherCoeffBottomRight;
                    tempPixels[index, ColorBytes.BlueIdx]  += db * ditherCoeffBottomRight;
                }
            }

            return(destImage);
        }