/// <inheritdoc /> public Bitmap Transform(Bitmap bitmap, IDistribution distribution) { if (bitmap is null) { throw new ArgumentNullException(nameof(bitmap)); } if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) { throw new NotSupportedException(Errors.NotSupported); } var cdf = GetCDF(bitmap); //get the new pixel values, according to a selected distribution var newPixels = _service.TransformToByte(cdf, distribution); var bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); var options = new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }; var step = Image.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8; var size = bitmap.Size; var stride = bitmapData.Stride; var(dstWidth, dstHeight) = (size.Width, size.Height); unsafe { var startPtr = (byte *)bitmapData.Scan0.ToPointer(); Parallel.For(0, dstHeight, options, y => { //get a start address var ptr = startPtr + y * stride; for (int x = 0; x < dstWidth; ++x, ptr += step) { //get a new pixel value, transofrming by a quantile ptr[0] = ptr[1] = ptr[2] = newPixels[ptr[0]]; } }); } bitmap.UnlockBits(bitmapData); return(bitmap); }
public byte[] TransformToByte(decimal[] cdf, IDistribution distribution) => _service.TransformToByte(cdf, distribution);