Beispiel #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 TestClone()
        {
            IndexedImage image = new IndexedImage {
                Size = new Size(3, 2)
            };

            image.Pixels[0] = 1;
            image.Pixels[1] = 2;
            image.Pixels[2] = 3;
            image.Pixels[3] = 1;
            image.Pixels[4] = 4;
            image.Pixels[5] = 2;
            image.CompletePalette();

            IndexedImage clonedImage = image.Clone(true, true);

            Assert.AreEqual(image.Size, clonedImage.Size);

            Assert.AreEqual(image.Pixels.Length, clonedImage.Pixels.Length);
            Assert.AreNotSame(image.Pixels, clonedImage.Pixels);
            Assert.AreEqual(image.Pixels[0], clonedImage.Pixels[0]);
            Assert.AreEqual(image.Pixels[1], clonedImage.Pixels[1]);
            Assert.AreEqual(image.Pixels[2], clonedImage.Pixels[2]);
            Assert.AreEqual(image.Pixels[3], clonedImage.Pixels[3]);
            Assert.AreEqual(image.Pixels[4], clonedImage.Pixels[4]);
            Assert.AreEqual(image.Pixels[5], clonedImage.Pixels[5]);

            Assert.AreEqual(image.Palette.Count, clonedImage.Palette.Count);
            Assert.AreNotSame(image.Palette, clonedImage.Palette);
            Assert.AreEqual(image.Palette[1], clonedImage.Palette[1]);
            Assert.AreEqual(image.Palette[2], clonedImage.Palette[2]);
            Assert.AreEqual(image.Palette[3], clonedImage.Palette[3]);
            Assert.AreEqual(image.Palette[4], clonedImage.Palette[4]);

            clonedImage[0, 0] = new Color(100);

            Assert.AreEqual(100, clonedImage.Pixels[0]);
            Assert.AreEqual(1, image.Pixels[0], "Changes in cloned image should not change original");
            Assert.AreEqual(5, clonedImage.Palette.Count);
            Assert.AreEqual(4, image.Palette.Count, "Changes in cloned image should not change original");

            PaletteTest.AssertColorInPalette(clonedImage.Palette, 100, 100, 0);
            PaletteTest.AssertColorInPalette(clonedImage.Palette, 1, 1, 3);
            PaletteTest.AssertColorInPalette(image.Palette, 1, 1, 0, 3);
        }
Beispiel #3
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);
        }