Esempio n. 1
0
            private Palette?InitializePalette(IReadableBitmapData source, IAsyncContext context)
            {
                using var alg = new TAlg();
                alg.Initialize(quantizer.maxColors, source);
                int width = source.Width;
                IReadableBitmapDataRow row = source.FirstRow;

                context.Progress?.New(DrawingOperation.InitializingQuantizer, source.Height);
                do
                {
                    if (context.IsCancellationRequested)
                    {
                        return(null);
                    }

                    // TODO: parallel if possible
                    for (int x = 0; x < width; x++)
                    {
                        Color32 c = row[x];

                        // handling alpha including full transparency
                        if (c.A != Byte.MaxValue)
                        {
                            c = c.A < quantizer.alphaThreshold ? default : c.BlendWithBackground(quantizer.backColor);
                        }
                        alg.AddColor(c);
                    }
                    context.Progress?.Increment();
                } while (row.MoveNextRow());

                Color32[]? palette = alg.GeneratePalette(context);
                return(context.IsCancellationRequested ? null : new Palette(palette !, quantizer.backColor, quantizer.alphaThreshold));
            }
Esempio n. 2
0
        private static void WriteRawBitmap(Bitmap bitmap, BinaryWriter bw)
        {
            Size size = bitmap.Size;

            bw.Write(size.Width);
            bw.Write(size.Height);
            PixelFormat pixelFormat = bitmap.PixelFormat;

            bw.Write((int)pixelFormat);
            if (pixelFormat.ToBitsPerPixel() <= 8)
            {
                Color[] palette = bitmap.Palette.Entries;
                bw.Write(palette.Length);
                foreach (Color color in palette)
                {
                    bw.Write(color.ToArgb());
                }
            }

            using (IReadableBitmapData data = bitmap.GetReadableBitmapData())
            {
                int width = data.RowSize >> 2;
                IReadableBitmapDataRow row = data.FirstRow;
                do
                {
                    for (int x = 0; x < width; x++)
                    {
                        bw.Write(row.ReadRaw <int>(x));
                    }
                } while (row.MoveNextRow());
            }
        }
Esempio n. 3
0
        protected static void AssertAreEqual(IReadableBitmapData source, IReadableBitmapData target, bool allowDifferentPixelFormats = false, Rectangle sourceRectangle = default, Point targetLocation = default)
        {
            if (sourceRectangle == default)
            {
                sourceRectangle = new Rectangle(Point.Empty, source.GetSize());
            }

            Assert.AreEqual(sourceRectangle.Size, target.GetSize());
            if (!allowDifferentPixelFormats)
            {
                Assert.AreEqual(source.PixelFormat, target.PixelFormat);
            }

            IReadableBitmapDataRow rowSrc = source[sourceRectangle.Y];
            IReadableBitmapDataRow rowDst = target[targetLocation.Y];

            bool tolerantCompare = source.GetType() != target.GetType() && source.PixelFormat.ToBitsPerPixel() > 32;

            for (int y = 0; y < sourceRectangle.Height; y++)
            {
                if (tolerantCompare)
                {
                    for (int x = 0; x < sourceRectangle.Width; x++)
                    {
                        Color32 c1 = rowSrc[x + sourceRectangle.X];
                        Color32 c2 = rowDst[x + targetLocation.X];

                        // this is faster than the asserts below
                        if (c1.A != c2.A ||
                            Math.Abs(c1.R - c2.R) > 5 ||
                            Math.Abs(c1.G - c2.G) > 5 ||
                            Math.Abs(c1.B - c2.B) > 5)
                        {
                            Assert.Fail($"Diff at {x}; {rowSrc.Index}: {c1} vs. {c2}");
                        }

                        //Assert.AreEqual(c1.A, c2.A, $"Diff at {x}; {rowSrc.Index}");
                        //Assert.That(() => Math.Abs(c1.R - c2.R), new LessThanOrEqualConstraint(1), $"Diff at {x}; {rowSrc.Index}");
                        //Assert.That(() => Math.Abs(c1.G - c2.G), new LessThanOrEqualConstraint(1), $"Diff at {x}; {rowSrc.Index}");
                        //Assert.That(() => Math.Abs(c1.B - c2.B), new LessThanOrEqualConstraint(1), $"Diff at {x}; {rowSrc.Index}");
                    }

                    continue;
                }

                for (int x = 0; x < sourceRectangle.Width; x++)
                {
                    Assert.AreEqual(rowSrc[x + sourceRectangle.X], rowDst[x + targetLocation.X], $"Diff at {x}; {rowSrc.Index}");
                }
            }
            while (rowSrc.MoveNextRow() && rowDst.MoveNextRow())
            {
                ;
            }
        }
Esempio n. 4
0
            private void PreprocessOddRow(int y)
            {
                // Odd rows are preprocessed so we don't need to complicate the IDitheringSession interface with processing path.
                // It is not even a significant overhead unless not every pixel is queried (eg. DrawInto with clipped region).
                IReadableBitmapDataRow row = source[y];

                // processing odd rows from right to left
                for (int x = ImageWidth - 1; x >= 0; x--)
                {
                    preprocessedResults[x] = DoErrorDiffusion(row[x], x, y);
                }
            }
Esempio n. 5
0
        public void ToGrayscaleTest()
        {
            using Bitmap bmp = Icons.Information.ExtractBitmap(new Size(256, 256));

            new PerformanceTest {
                Iterations = 100, CpuAffinity = null
            }
            .AddCase(() =>
            {
                using var result = new Bitmap(bmp.Width, bmp.Height);
                using (Graphics g = Graphics.FromImage(result))
                {
                    // Grayscale color matrix
                    var colorMatrix = new ColorMatrix(new float[][]
                    {
                        new float[] { ColorExtensions.RLum, ColorExtensions.RLum, ColorExtensions.RLum, 0, 0 },
                        new float[] { ColorExtensions.GLum, ColorExtensions.GLum, ColorExtensions.GLum, 0, 0 },
                        new float[] { ColorExtensions.BLum, ColorExtensions.BLum, ColorExtensions.BLum, 0, 0 },
                        new float[] { 0, 0, 0, 1, 0 },
                        new float[] { 0, 0, 0, 0, 1 }
                    });

                    using (var attrs = new ImageAttributes())
                    {
                        attrs.SetColorMatrix(colorMatrix);
                        g.DrawImage(bmp, new Rectangle(0, 0, result.Width, result.Height), 0, 0, result.Width, result.Height, GraphicsUnit.Pixel, attrs);
                    }
                }
            }, "Graphics.DrawImage(..., ImageAttributes)")
            .AddCase(() =>
            {
                using var result = new Bitmap(bmp.Width, bmp.Height);
                using IReadableBitmapData src = bmp.GetReadableBitmapData();
                using IWritableBitmapData dst = result.GetWritableBitmapData();
                IReadableBitmapDataRow rowSrc = src.FirstRow;
                IWritableBitmapDataRow rowDst = dst.FirstRow;
                do
                {
                    for (int x = 0; x < src.Width; x++)
                    {
                        rowDst[x] = rowSrc[x].ToGray();
                    }
                } while (rowSrc.MoveNextRow() && rowDst.MoveNextRow());
            }, "Sequential processing")
            .AddCase(() =>
            {
                using var result = bmp.ToGrayscale();
            }, "ImageExtensions.ToGrayscale")
            .DoTest()
            .DumpResults(Console.Out);
        }