private void TransformPerPixelBase(ImageBuffer target, IList<Point> path = null, Int32 parallelTaskCount = 4, params Delegate[] passes) { // checks parameters Guard.CheckNull(target, "target"); Guard.CheckNull(passes, "passes"); // creates internal quantizer if needed UpdatePalette(); target.UpdatePalette(); // checks the dimensions if (Width != target.Width || Height != target.Height) { const String message = "Both images have to have the same dimensions."; throw new ArgumentOutOfRangeException(message); } // determines mode Boolean isAdvanced = passes.Length > 0 && passes[0] is TransformPixelAdvancedFunction; // creates default path, if none is available if (path == null) path = StandardPathProvider.CreatePath(Width, Height); // process the image in a parallel manner Action<LineTask> transformPerPixel = lineTask => { // creates individual pixel structures per task Pixel sourcePixel = CreatePixel(); Pixel targetPixel = target.CreatePixel(); Delegate pass = passes[lineTask.PassIndex]; // enumerates the pixels row by row for (Int32 pathOffset = lineTask.StartOffset; pathOffset < lineTask.EndOffset; pathOffset++) { Point point = path[pathOffset]; Boolean allowWrite; // enumerates the pixel, and returns the control to the outside sourcePixel.Update(point.X, point.Y); targetPixel.Update(point.X, point.Y); // when read is allowed, retrieves current value (in bytes) if (CanRead) ReadPixel(sourcePixel); if (target.CanRead) target.ReadPixel(targetPixel); // process the pixel by custom user operation if (isAdvanced) { TransformPixelAdvancedFunction transformAdvancedFunction = (TransformPixelAdvancedFunction) pass; allowWrite = transformAdvancedFunction(lineTask.PassIndex, sourcePixel, targetPixel, this, target); } else // use simplified version with pixel parameters only { TransformPixelFunction transformFunction = (TransformPixelFunction) pass; allowWrite = transformFunction(lineTask.PassIndex, sourcePixel, targetPixel); } // when write is allowed, copies the value back to the row buffer if (target.CanWrite && allowWrite) target.WritePixel(targetPixel); } }; // transforms image per pixel for (Int32 passIndex = 0; passIndex < passes.Length; passIndex++) { ProcessInParallel(passIndex, transformPerPixel, path, parallelTaskCount); } }
public void TransformPerPixelAdvanced(PixelFormat targetFormat, List<Color> palette, out Image targetImage, IList<Point> path = null, Int32 parallelTaskCount = 4, params TransformPixelAdvancedFunction[] passes) { // checks parameters Guard.CheckNull(targetFormat, "targetFormat"); // creates a target bitmap in an appropriate format targetImage = new Bitmap(Width, Height, targetFormat); // sets image palette if needed if (targetFormat.IsIndexed()) targetImage.SetPalette(palette); // wraps target image to a buffer using (ImageBuffer target = new ImageBuffer(targetImage, ImageLockMode.WriteOnly)) { TransformPerPixelBase(target, path, parallelTaskCount, passes); } }
internal void DrawEllipse(Pen pen, int x, int y, int width, int height) { var ellipsePixels = DrawEllipseCentered(_bitmap.Width, _bitmap.Height, x + width / 2, y + height / 2, width / 2, height / 2); var color = pen.Color; if (_dummyImageBuffer == null) _dummyImageBuffer = new ImageBuffer(new Bitmap(_bitmap.Width, _bitmap.Height, _bitmap.PixelFormat), ImageLockMode.ReadOnly); _dummyImageBuffer.TransformPerPixel(null, ref _bitmap, ellipsePixels.Select(idx => new Point(idx % _bitmap.Width, idx / _bitmap.Width)).ToList(), ParallelTaskCount, (passIndex, sourcePixel, targetPixel) => { targetPixel.SetColor(color, _quantizer); return true; }); }
public void Dither(ImageBuffer target, IColorDitherer ditherer, IColorQuantizer quantizer, Int32 colorCount, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(target, "target"); Guard.CheckNull(ditherer, "ditherer"); Guard.CheckNull(quantizer, "quantizer"); // prepares ditherer for another round ditherer.Prepare(quantizer, colorCount, this, target); // processes the image via the ditherer IList<Point> path = ditherer.GetPointPath(Width, Height); TransformPerPixel(target, path, parallelTaskCount, ditherer.ProcessPixel); }
public void Quantize(ImageBuffer target, IColorQuantizer quantizer, IColorDitherer ditherer, Int32 colorCount, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(target, "target"); Guard.CheckNull(quantizer, "quantizer"); // initializes quantization parameters Boolean isTargetIndexed = target.PixelFormat.IsIndexed(); // prepares the palette if needed List<Color> targetPalette = isTargetIndexed ? SynthetizePalette(quantizer, colorCount, parallelTaskCount) : null; // updates the bitmap palette target.bitmap.SetPalette(targetPalette); target.UpdatePalette(true); // prepares ditherer (optional) if (ditherer != null) ditherer.Prepare(quantizer, colorCount, this, target); // prepares the quantization function TransformPixelFunction quantize = (passIndex, sourcePixel, targetPixel) => { // reads the pixel color Color color = sourcePixel.GetColor(); // converts alpha to solid color color = QuantizationHelper.ConvertAlpha(color); // quantizes the pixel targetPixel.SetColor(color, quantizer); // marks pixel as processed by default Boolean result = true; // preforms inplace dithering (optional) if (ditherer != null && ditherer.IsInplace) { result = ditherer.ProcessPixel(passIndex, sourcePixel, targetPixel); } // returns the result return result; }; // generates the target image IList<Point> path = quantizer.GetPointPath(Width, Height); TransformPerPixelBase(target, path, parallelTaskCount, quantize); // preforms non-inplace dithering (optional) if (ditherer != null && !ditherer.IsInplace) { Dither(target, ditherer, quantizer, colorCount, 1); } // finishes the dithering (optional) if (ditherer != null) ditherer.Finish(); // cleans up the quantizer quantizer.Finish(); }
public static void TransformImagePerPixelAdvanced(Image sourceImage, PixelFormat targetFormat, List<Color> palette, out Image targetImage, IList<Point> path = null, Int32 parallelTaskCount = 4, params TransformPixelAdvancedFunction[] passes) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadWrite)) { source.TransformPerPixelAdvanced(targetFormat, palette, out targetImage, path, parallelTaskCount, passes); } }
public Double CalculateNormalizedMeanError(ImageBuffer target, Int32 parallelTaskCount = 4) { return CalculateMeanError(target, parallelTaskCount) / 255.0; }
public static void DitherImage(ImageBuffer source, ImageBuffer target, IColorDitherer ditherer, IColorQuantizer quantizer, Int32 colorCount, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(source, "source"); // use other override to calculate error source.Dither(target, ditherer, quantizer, colorCount, parallelTaskCount); }
public static void DitherImage(Image sourceImage, Image targetImage, IColorDitherer ditherer, IColorQuantizer quantizer, Int32 colorCount, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); Guard.CheckNull(targetImage, "targetImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadOnly)) using (ImageBuffer target = new ImageBuffer(targetImage, ImageLockMode.ReadOnly)) { // use other override to calculate error source.Dither(target, ditherer, quantizer, colorCount, parallelTaskCount); } }
public static void ChangeFormat(Image sourceImage, PixelFormat targetFormat, IColorQuantizer quantizer, out Image targetImage, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadOnly)) { ChangeFormat(source, targetFormat, quantizer, out targetImage, parallelTaskCount); } }
public static void CorrectImageGamma(Image sourceImage, Single gamma, IColorQuantizer quantizer, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadOnly)) { source.CorrectGamma(gamma, quantizer, parallelTaskCount); } }
public static void ChangeFormat(ImageBuffer source, PixelFormat targetFormat, IColorQuantizer quantizer, out Image targetImage, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(source, "source"); // creates a target bitmap in an appropriate format targetImage = new Bitmap(source.Width, source.Height, targetFormat); // wraps target image to a buffer using (ImageBuffer target = new ImageBuffer(targetImage, ImageLockMode.WriteOnly)) { source.ChangeFormat(target, quantizer, parallelTaskCount); } }
public static Double CalculateImageNormalizedMeanError(Image sourceImage, Image targetImage, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); Guard.CheckNull(targetImage, "targetImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadOnly)) using (ImageBuffer target = new ImageBuffer(targetImage, ImageLockMode.ReadOnly)) { // use other override to calculate error return source.CalculateNormalizedMeanError(target, parallelTaskCount); } }
public static Double CalculateImageNormalizedMeanError(ImageBuffer source, ImageBuffer target, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(source, "source"); // use other override to calculate error return source.CalculateNormalizedMeanError(target, parallelTaskCount); }
public static void TransformImagePerPixelAdvanced(ImageBuffer source, ImageBuffer target, IList<Point> path = null, Int32 parallelTaskCount = 4, params TransformPixelAdvancedFunction[] passes) { source.TransformPerPixelAdvanced(target, path, parallelTaskCount, passes); }
public static void ProcessPerPixel(ImageBuffer source, IList<Point> path = null, Int32 parallelTaskCount = 4, params ProcessPixelAdvancedFunction[] passes) { source.ProcessPerPixelBase(path, parallelTaskCount, passes); }
public static void TransformImagePerPixelAdvanced(ImageBuffer source, PixelFormat targetFormat, List<Color> palette, out Image targetImage, IList<Point> path = null, Int32 parallelTaskCount = 4, params TransformPixelAdvancedFunction[] passes) { source.TransformPerPixelAdvanced(targetFormat, palette, out targetImage, path, parallelTaskCount, passes); }
public static void ProcessPerPixel(Image sourceImage, IList<Point> path = null, Int32 parallelTaskCount = 4, params ProcessPixelAdvancedFunction[] passes) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadOnly)) { source.ProcessPerPixelBase(path, parallelTaskCount, passes); } }
public Double CalculateMeanError(ImageBuffer target, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(target, "target"); // initializes the error Int64 totalError = 0; // prepares the function TransformPixelFunction calculateMeanError = (passIndex, sourcePixel, targetPixel) => { Color sourceColor = sourcePixel.GetColor(); Color targetColor = targetPixel.GetColor(); totalError += ColorModelHelper.GetColorEuclideanDistance(ColorModel.RedGreenBlue, sourceColor, targetColor); return false; }; // performs the image scan, using a chosen method IList<Point> standardPath = new StandardPathProvider().GetPointPath(Width, Height); TransformPerPixelBase(target, standardPath, parallelTaskCount, calculateMeanError); // returns the calculates RMSD return Math.Sqrt(totalError/(3.0*Width*Height)); }
public static Image QuantizeImage(ImageBuffer source, IColorQuantizer quantizer, Int32 colorCount, Int32 parallelTaskCount = 4) { // performs the pure quantization wihout dithering return QuantizeImage(source, quantizer, null, colorCount, parallelTaskCount); }
public void ChangeFormat(ImageBuffer target, IColorQuantizer quantizer, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(target, "target"); Guard.CheckNull(quantizer, "quantizer"); // gathers some information about the target format Boolean hasSourceAlpha = PixelFormat.HasAlpha(); Boolean hasTargetAlpha = target.PixelFormat.HasAlpha(); Boolean isTargetIndexed = target.PixelFormat.IsIndexed(); Boolean isSourceDeepColor = PixelFormat.IsDeepColor(); Boolean isTargetDeepColor = target.PixelFormat.IsDeepColor(); // prepares the palette if needed if (isTargetIndexed) { // synthetises palette using provided quantizer List<Color> targetPalette = SynthetizePalette(quantizer, target.PixelFormat.GetColorCount(), parallelTaskCount); // updates the bitmap palette target.bitmap.SetPalette(targetPalette); target.UpdatePalette(true); } // prepares the quantization function TransformPixelFunction changeFormat = (passIndex, sourcePixel, targetPixel) => { // if both source and target formats are deep color formats, copies a value directly if (isSourceDeepColor && isTargetDeepColor) { //UInt64 value = sourcePixel.Value; //targetPixel.SetValue(value); } else { // retrieves a source image color Color color = sourcePixel.GetColor(); // if alpha is not present in the source image, but is present in the target, make one up if (!hasSourceAlpha && hasTargetAlpha) { Int32 argb = 255 << 24 | color.R << 16 | color.G << 8 | color.B; color = Color.FromArgb(argb); } // sets the color to a target pixel targetPixel.SetColor(color, quantizer); } // allows to write (obviously) the transformed pixel return true; }; // generates the target image IList<Point> standardPath = new StandardPathProvider().GetPointPath(Width, Height); TransformPerPixelBase(target, standardPath, parallelTaskCount, changeFormat); }
public static Image QuantizeImage(ImageBuffer source, IColorQuantizer quantizer, IColorDitherer ditherer, Int32 colorCount, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(source, "source"); // creates a target bitmap in an appropriate format PixelFormat targetPixelFormat = Extend.GetFormatByColorCount(colorCount); Image result = new Bitmap(source.Width, source.Height, targetPixelFormat); // lock mode ImageLockMode lockMode = ditherer == null ? ImageLockMode.WriteOnly : ImageLockMode.ReadWrite; // wraps target image to a buffer using (ImageBuffer target = new ImageBuffer(result, lockMode)) { source.Quantize(target, quantizer, ditherer, colorCount, parallelTaskCount); return result; } }
public void Quantize(ImageBuffer target, IColorQuantizer quantizer, Int32 colorCount, Int32 parallelTaskCount = 4) { // performs the pure quantization wihout dithering Quantize(target, quantizer, null, colorCount, parallelTaskCount); }
public static Image QuantizeImage(Image sourceImage, IColorQuantizer quantizer, IColorDitherer ditherer, Int32 colorCount, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); // lock mode ImageLockMode lockMode = ditherer == null ? ImageLockMode.ReadOnly : ImageLockMode.ReadWrite; // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, lockMode)) { return QuantizeImage(source, quantizer, ditherer, colorCount, parallelTaskCount); } }
public void TransformPerPixelAdvanced(ImageBuffer target, IList<Point> path = null, Int32 parallelTaskCount = 4, params TransformPixelAdvancedFunction[] passes) { TransformPerPixelBase(target, path, parallelTaskCount, passes); }
public static void ScanImageColors(Image sourceImage, IColorQuantizer quantizer, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadOnly)) { source.ScanColors(quantizer, parallelTaskCount); } }
/// <summary> /// Initializes a new instance of the <see cref="Pixel"/> struct. /// </summary> public Pixel(ImageBuffer parent) { Parent = parent; Initialize(); }
public static List<Color> SynthetizeImagePalette(Image sourceImage, IColorQuantizer quantizer, Int32 colorCount, Int32 parallelTaskCount = 4) { // checks parameters Guard.CheckNull(sourceImage, "sourceImage"); // wraps source image to a buffer using (ImageBuffer source = new ImageBuffer(sourceImage, ImageLockMode.ReadOnly)) { return source.SynthetizePalette(quantizer, colorCount, parallelTaskCount); } }
internal void DrawLine(Pen pen, Point pt1, Point pt2) { var linePixels = DrawLine(_bitmap.Width, _bitmap.Height, pt1.X, pt1.Y, pt2.X, pt2.Y); var color = pen.Color; if (_dummyImageBuffer == null) _dummyImageBuffer = new ImageBuffer(new Bitmap(_bitmap.Width, _bitmap.Height, _bitmap.PixelFormat), ImageLockMode.ReadOnly); _dummyImageBuffer.TransformPerPixel(null, ref _bitmap, linePixels.Select(idx => new Point(idx % _bitmap.Width, idx / _bitmap.Width)).ToList(), ParallelTaskCount, (passIndex, sourcePixel, targetPixel) => { targetPixel.SetColor(color, _quantizer); return true; }); }
public void TransformPerPixel(List<Color> palette, ref Image targetImage, IList<Point> path = null, Int32 parallelTaskCount = 4, params TransformPixelFunction[] passes) { // checks parameters Guard.CheckNull(targetImage, "targetImage"); // creates a target bitmap in an appropriate format var targetFormat = targetImage.PixelFormat; // sets image palette if needed if (palette != null && targetFormat.IsIndexed()) targetImage.SetPalette(palette); // wraps target image to a buffer using (var target = new ImageBuffer(targetImage, ImageLockMode.WriteOnly)) { TransformPerPixelBase(target, path, parallelTaskCount, passes); } }