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); }
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); }
/// <summary> /// Gets a managed read-write accessor for a <see cref="WriteableBitmapData"/> instance. /// </summary> /// <param name="bitmap">The bitmap to get the managed accessor.</param> /// <returns>An <see cref="IReadWriteBitmapData"/> instance that provides managed access to the specified <see cref="bitmap"/>.</returns> public static IReadWriteBitmapData GetReadWriteBitmapData(this WriteableBitmap bitmap) { if (bitmap == null) { throw new ArgumentNullException(nameof(bitmap)); } if (bitmap.IsFrozen) { throw new ArgumentException("Bitmap must not be frozen"); } var format = bitmap.Format; // Actually you can support any other formats, including non-natively supported ones by custom PixelFormatInfo and getter/setter delegates var pixelFormat = format == PixelFormats.Bgra32 ? PixelFormat.Format32bppArgb : format == PixelFormats.Pbgra32 ? PixelFormat.Format32bppPArgb : format == PixelFormats.Bgr32 ? PixelFormat.Format32bppRgb : format == PixelFormats.Bgr24 ? PixelFormat.Format24bppRgb : throw new NotSupportedException(bitmap.Format.ToString()); bitmap.Lock(); return(BitmapDataFactory.CreateBitmapData(bitmap.BackBuffer, new Size(bitmap.PixelWidth, bitmap.PixelHeight), bitmap.BackBufferStride, pixelFormat, disposeCallback: () => { bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight)); bitmap.Unlock(); })); }
protected static IReadWriteBitmapData GenerateAlphaGradientBitmapData(Size size) { var result = BitmapDataFactory.CreateBitmapData(size); GenerateAlphaGradient(result); return(result); }
public void CopyToClippedTest(PixelFormat pixelFormat) { using IReadableBitmapData src = Icons.Information.ExtractBitmap(new Size(256, 256)).ConvertPixelFormat(pixelFormat).GetReadableBitmapData(); Size targetSize = new Size(128, 128); using IReadWriteBitmapData dst = BitmapDataFactory.CreateBitmapData(targetSize, pixelFormat); new PerformanceTest { CpuAffinity = null, Iterations = 10_000 }
public void CopyToTest(PixelFormat pixelFormat) { if (!pixelFormat.IsSupportedNatively()) { Assert.Inconclusive($"Pixel format {pixelFormat} is not supported on current platform"); } Size size = new Size(256, 256); using var bmpSrc = Icons.Information.ExtractBitmap(size).ConvertPixelFormat(pixelFormat); new PerformanceTest { TestName = pixelFormat.ToString(), Iterations = 100, CpuAffinity = null } .AddCase(() => { using var bmpDst = new Bitmap(size.Width, size.Height, pixelFormat); using (var g = Graphics.FromImage(bmpDst)) { g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.CompositingMode = CompositingMode.SourceCopy; // so it is the same as CopyTo (and is much faster) g.DrawImage(bmpSrc, Point.Empty); } }, "Graphics.DrawImage") .AddCase(() => { using var bmpDst = new Bitmap(size.Width, size.Height, pixelFormat); using (var dataSrc = bmpSrc.GetReadableBitmapData()) using (var dataDst = bmpDst.GetWritableBitmapData()) { dataSrc.CopyTo(dataDst, Point.Empty); } }, "ImageExtensions.CopyTo (native to native)") .AddCase(() => { using var bitmapDataDst = BitmapDataFactory.CreateBitmapData(size, pixelFormat); using (var dataSrc = bmpSrc.GetReadableBitmapData()) { dataSrc.CopyTo(bitmapDataDst, Point.Empty); } }, "ImageExtensions.CopyTo (native to managed)") .DoTest() .DumpResults(Console.Out); }
public void ReplaceColorTest() { using var bmp = Icons.Shield.ExtractBitmap(new Size(128, 128), true).Resize(new Size(256, 256)); new PerformanceTest { Iterations = 100, CpuAffinity = null } .AddCase(() => { using var result = bmp.CloneBitmap(); result.MakeTransparent(Color.Black); }, "Bitmap.MakeTransparent") .AddCase(() => { using var result = bmp.CloneBitmap(); result.ReplaceColor(Color.Black, Color.Transparent); }, "BitmapExtensions.ReplaceColor") .AddCase(() => { using var result = bmp.CloneBitmap(); using (IBitmapDataInternal bitmapData = BitmapDataFactory.CreateBitmapData(result, ImageLockMode.ReadWrite)) { Color32 from = new Color32(Color.Black); Color32 to = new Color32(Color.Transparent); IBitmapDataRowInternal row = bitmapData.DoGetRow(0); do { for (int x = 0; x < bitmapData.Width; x++) { if (row[x] != from) { continue; } row[x] = to; } } while (row.MoveNextRow()); } }, "Sequential processing") .DoTest() .DumpResults(Console.Out); }
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); }