public void QuantizePerformanceTest()
        {
            //using var bmpRef = new Bitmap(@"D:\Letolt\MYSTY8RQER62.jpg");
            using var bmpRef = Icons.Information.ExtractBitmap(new Size(256, 256));
            IQuantizer quantizer = PredefinedColorsQuantizer.SystemDefault8BppPalette();

            new PerformanceTest {
                TestName = $"{bmpRef.Width}x{bmpRef.Height}@{bmpRef.GetColorCount()}", Iterations = 100, CpuAffinity = null
            }
            .AddCase(() =>
            {
                using var result = bmpRef.CloneBitmap();
                result.Quantize(quantizer);
            }, "BitmapExtensions.Quantize")
            .AddCase(() =>
            {
                using var result = bmpRef.CloneBitmap();
                using (IBitmapDataInternal bitmapData = BitmapDataFactory.CreateBitmapData(result, ImageLockMode.ReadWrite))
                    using (IQuantizingSession session = quantizer.Initialize(bitmapData))
                    {
                        var row   = bitmapData.DoGetRow(0);
                        int width = bitmapData.Width;
                        do
                        {
                            for (int x = 0; x < width; x++)
                            {
                                row.DoSetColor32(x, session.GetQuantizedColor(row.DoGetColor32(x)));
                            }
                        } while (row.MoveNextRow());
                    }
            }, "Sequential quantization")
            .DoTest()
            .DumpResults(Console.Out);
        }
        public void DitherPerformanceTest(bool errorDiffusion)
        {
            using var bmpRef = Icons.Information.ExtractBitmap(new Size(256, 256));
            IQuantizer quantizer = PredefinedColorsQuantizer.SystemDefault8BppPalette();
            IDitherer  ditherer  = errorDiffusion ? (IDitherer)ErrorDiffusionDitherer.FloydSteinberg : OrderedDitherer.Bayer8x8;

            new PerformanceTest {
                TestName = $"{bmpRef.Width}x{bmpRef.Height}@{bmpRef.GetColorCount()} {(errorDiffusion ? "Error Diffusion" : "Ordered")}", Iterations = 100, CpuAffinity = null
            }
            .AddCase(() =>
            {
                using var result = bmpRef.CloneBitmap();
                result.Dither(quantizer, ditherer);
            }, "BitmapExtensions.Dither")
            .AddCase(() =>
            {
                using var result = bmpRef.CloneBitmap();
                using (IBitmapDataInternal bitmapData = BitmapDataFactory.CreateBitmapData(result, ImageLockMode.ReadWrite))
                    using (IQuantizingSession quantizingSession = quantizer.Initialize(bitmapData))
                        using (IDitheringSession ditheringSession = ditherer.Initialize(bitmapData, quantizingSession))
                        {
                            var row   = bitmapData.DoGetRow(0);
                            int width = bitmapData.Width;
                            do
                            {
                                for (int x = 0; x < width; x++)
                                {
                                    row.DoSetColor32(x, ditheringSession.GetDitheredColor(row.DoGetColor32(x), x, row.Index));
                                }
                            } while (row.MoveNextRow());
                        }
            }, "Sequential dithering")
            .DoTest()
            .DumpResults(Console.Out);
        }
Example #3
0
        internal void PerformDraw(IQuantizer quantizer, IDitherer ditherer)
        {
            if (quantizer == null)
            {
                PerformDrawDirect();
                return;
            }

            IReadableBitmapData initSource = SourceRectangle.Size == Source.GetSize()
                ? Source
                : Source.Clip(SourceRectangle);

            try
            {
                Debug.Assert(!quantizer.InitializeReliesOnContent || !Source.HasMultiLevelAlpha(), "This draw performs blending on-the-fly but the used quantizer would require two-pass processing");
                context.Progress?.New(DrawingOperation.InitializingQuantizer);
                using (IQuantizingSession quantizingSession = quantizer.Initialize(initSource, context))
                {
                    if (context.IsCancellationRequested)
                    {
                        return;
                    }
                    if (quantizingSession == null)
                    {
                        throw new InvalidOperationException(Res.ImagingQuantizerInitializeNull);
                    }

                    // quantizing without dithering
                    if (ditherer == null)
                    {
                        PerformDrawWithQuantizer(quantizingSession);
                        return;
                    }

                    // quantizing with dithering
                    Debug.Assert(!ditherer.InitializeReliesOnContent || !Source.HasMultiLevelAlpha(), "This draw performs blending on-the-fly but the used ditherer would require two-pass processing");

                    context.Progress?.New(DrawingOperation.InitializingDitherer);
                    using IDitheringSession ditheringSession = ditherer.Initialize(initSource, quantizingSession, context);
                    if (context.IsCancellationRequested)
                    {
                        return;
                    }
                    if (ditheringSession == null)
                    {
                        throw new InvalidOperationException(Res.ImagingDithererInitializeNull);
                    }

                    PerformDrawWithDithering(quantizingSession, ditheringSession);
                }
            }
            finally
            {
                if (!ReferenceEquals(initSource, Source))
                {
                    initSource.Dispose();
                }
            }
        }
        public void ClearWithDitheringTest(PixelFormat pixelFormat, uint argb, bool errorDiffusion)
        {
            const int size     = 512;
            Color     color    = Color.FromArgb((int)argb);
            var       ditherer = errorDiffusion ? (IDitherer)ErrorDiffusionDitherer.FloydSteinberg : OrderedDitherer.Bayer8x8;

            new PerformanceTest {
                TestName = $"{pixelFormat} {size}x{size} {(errorDiffusion ? "Error Diffusion" : "Ordered Dithering")}", Iterations = 10, CpuAffinity = null
            }
            .AddCase(() =>
            {
                using var bmp = new Bitmap(size, size, pixelFormat);
                using IBitmapDataInternal acc = BitmapDataFactory.CreateBitmapData(bmp, ImageLockMode.ReadWrite);
                IQuantizer quantizer          = PredefinedColorsQuantizer.FromBitmapData(acc);
                var c = new Color32(color);
                using (IQuantizingSession quantizingSession = quantizer.Initialize(acc))
                    using (IDitheringSession ditheringSession = ditherer.Initialize(acc, quantizingSession))
                    {
                        IReadWriteBitmapDataRow row = acc.DoGetRow(0);
                        do
                        {
                            for (int x = 0; x < acc.Width; x++)
                            {
                                row[x] = ditheringSession.GetDitheredColor(c, x, row.Index);
                            }
                        } while (row.MoveNextRow());
                    }
            }, "Sequential clear")
            .AddCase(() =>
            {
                using var bmp = new Bitmap(size, size, pixelFormat);
                bmp.Clear(color, ditherer);
            }, "BitmapDataAccessor.Clear")
            .DoTest()
            .DumpResults(Console.Out);
        }