/// <summary> /// Rotates the image 270 degrees clockwise at the centre point. /// </summary> /// <param name="target">The target image.</param> /// <param name="source">The source image.</param> private void Rotate270(ImageBase <T, TP> target, ImageBase <T, TP> source) { int width = source.Width; int height = source.Height; Image <T, TP> temp = new Image <T, TP>(height, width); using (IPixelAccessor <T, TP> sourcePixels = source.Lock()) using (IPixelAccessor <T, TP> tempPixels = temp.Lock()) { Parallel.For( 0, height, this.ParallelOptions, y => { for (int x = 0; x < width; x++) { int newX = height - y - 1; newX = height - newX - 1; int newY = width - x - 1; tempPixels[newX, newY] = sourcePixels[x, y]; } this.OnRowProcessed(); }); } target.SetPixels(height, width, temp.Pixels); }
/// <inheritdoc/> protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) { if (source.Bounds == target.Bounds) { target.SetPixels(target.Width, target.Height, source.Pixels); return; } int targetY = this.cropRectangle.Y; int startX = targetRectangle.X; int targetX = this.cropRectangle.X; int endX = this.cropRectangle.Width; int maxX = endX - 1; int maxY = this.cropRectangle.Bottom - 1; Parallel.For( startY, endY, y => { for (int x = startX; x < endX; x++) { int offsetY = y + targetY; offsetY = offsetY.Clamp(0, maxY); int offsetX = x + targetX; offsetX = offsetX.Clamp(0, maxX); target[x, y] = source[offsetX, offsetY]; } this.OnRowProcessed(); }); }
public virtual void Sample(ImageBase source, ImageBase target, int width, int height) { byte[] pixels = new byte[width * height * 4]; if (Parallelism > 1) { int partitionCount = Parallelism; Task[] tasks = new Task[partitionCount]; for (int p = 0; p < partitionCount; p++) { int current = p; tasks[p] = Task.Run(() => { int batchSize = height / partitionCount; int yBegin = current * batchSize; int yEnd = (current == partitionCount - 1 ? height : yBegin + batchSize); Sample(source, width, height, yBegin, yEnd, pixels); }); } Task.WaitAll(tasks); } else { Sample(source, width, height, 0, height, pixels); } target.SetPixels(width, height, pixels); }
/// <summary> /// Creates a new target to contain the results of the matrix transform. /// </summary> /// <param name="target">Target image to apply the process to.</param> /// <param name="sourceRectangle">The source rectangle.</param> /// <param name="processMatrix">The processing matrix.</param> protected static void CreateNewTarget(ImageBase <TColor, TPacked> target, Rectangle sourceRectangle, Matrix3x2 processMatrix) { Matrix3x2 sizeMatrix; if (Matrix3x2.Invert(processMatrix, out sizeMatrix)) { Rectangle rectangle = ImageMaths.GetBoundingRectangle(sourceRectangle, sizeMatrix); target.SetPixels(rectangle.Width, rectangle.Height, new TColor[rectangle.Width * rectangle.Height]); } }
public void Resize(ImageBase source, ImageBase target, int width, int height) { byte[] newPixels = new byte[width * height * 4]; double xFactor = (double)source.PixelWidth / width; double yFactor = (double)source.PixelHeight / height; int dstOffsetLine = 0; int dstOffset = 0; int srcOffsetLine = 0; int srcOffset = 0; byte[] sourcePixels = source.Pixels; for (int y = 0; y < height; y++) { dstOffsetLine = 4 * width * y; // Calculate the line offset at the source image, where the pixels should be get from. srcOffsetLine = 4 * source.PixelWidth * (int)(y * yFactor); for (int x = 0; x < width; x++) { dstOffset = dstOffsetLine + 4 * x; srcOffset = srcOffsetLine + 4 * (int)(x * xFactor); newPixels[dstOffset + 0] = sourcePixels[srcOffset + 0]; newPixels[dstOffset + 1] = sourcePixels[srcOffset + 1]; newPixels[dstOffset + 2] = sourcePixels[srcOffset + 2]; newPixels[dstOffset + 3] = sourcePixels[srcOffset + 3]; } } target.SetPixels(width, height, newPixels); }
private void ConvertFromYCbCr(int imageWidth, int imageHeight, ImageBase image) { int scale = comp[0].h/comp[1].h; Color2[] pixels = new Color2[imageWidth*imageHeight]; Parallel.For(0, imageHeight, Bootstrapper.instance.ParallelOptions, y =>{ int yo = ycbcrImage.get_row_y_offset(y); int co = ycbcrImage.get_row_c_offset(y); for (int x = 0; x < imageWidth; x++){ byte yy = ycbcrImage.pix_y[yo + x]; byte cb = ycbcrImage.pix_cb[co + (x/scale)]; byte cr = ycbcrImage.pix_cr[co + (x/scale)]; int index = y*imageWidth + x; Color2 color = new YCbCr2(yy, cb, cr); Color2 packed = Color2.FromArgb(color.A, color.R, color.G, color.B); pixels[index] = packed; } }); image.SetPixels(imageWidth, imageHeight, pixels); AssignResolution(image); }
private void ConvertFromRgb(int imageWidth, int imageHeight, ImageBase image) { int scale = comp[0].h/comp[1].h; Color2[] pixels = new Color2[imageWidth*imageHeight]; Parallel.For(0, imageHeight, Bootstrapper.instance.ParallelOptions, y =>{ int yo = ycbcrImage.get_row_y_offset(y); int co = ycbcrImage.get_row_c_offset(y); for (int x = 0; x < imageWidth; x++){ byte red = ycbcrImage.pix_y[yo + x]; byte green = ycbcrImage.pix_cb[co + (x/scale)]; byte blue = ycbcrImage.pix_cr[co + (x/scale)]; int index = (y*imageWidth) + x; Color2 packed = Color2.FromArgb(red, green, blue); pixels[index] = packed; } }); image.SetPixels(imageWidth, imageHeight, pixels); AssignResolution(image); }
private void ConvertFromGrayScale(int imageWidth, int imageHeight, ImageBase image) { Color2[] pixels = new Color2[imageWidth*imageHeight]; Parallel.For(0, imageHeight, Bootstrapper.instance.ParallelOptions, y =>{ int yoff = grayImage.GetRowOffset(y); for (int x = 0; x < imageWidth; x++){ int offset = (y*imageWidth) + x; byte rgb = grayImage.pixels[yoff + x]; Color2 packed = Color2.FromArgb(rgb, rgb, rgb); pixels[offset] = packed; } }); image.SetPixels(imageWidth, imageHeight, pixels); AssignResolution(image); }
/// <inheritdoc/> protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle) { ImageBase temp = new Image(source.Width, source.Height); // Detect the edges. new Sobel().Apply(temp, source, sourceRectangle); // Apply threshold binarization filter. new Threshold(.5f).Apply(temp, temp, sourceRectangle); // Search for the first white pixels Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); // Reset the target pixel to the correct size. target.SetPixels(rectangle.Width, rectangle.Height, new float[rectangle.Width * rectangle.Height * 4]); this.cropRectangle = rectangle; }
public void Resize(ImageBase source, ImageBase target, int width, int height) { byte[] newPixels = new byte[width * height * 4]; byte[] sourcePixels = source.Pixels; var GetColor = new Func<double, double, int, byte>((x, y, offset) => sourcePixels[(int)((y * source.PixelWidth + x) * 4 + offset)]); double factorX = (double)source.PixelWidth / width; double factorY = (double)source.PixelHeight / height; double fractionX, oneMinusX, l, r; double fractionY, oneMinusY, t, b; byte c1, c2, c3, c4, b1, b2; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int dstOffset = (y * width + x) * 4; l = (int)Math.Floor(x * factorX); t = (int)Math.Floor(y * factorY); r = l + 1; b = t + 1; if (r >= source.PixelWidth) { r = l; } if (b >= source.PixelHeight) { b = t; } fractionX = x * factorX - l; fractionY = y * factorY - t; oneMinusX = 1.0 - fractionX; oneMinusY = 1.0 - fractionY; var function = new Func<int, byte>(offset => { c1 = GetColor(l, t, offset); c2 = GetColor(r, t, offset); c3 = GetColor(l, b, offset); c4 = GetColor(r, b, offset); b1 = (byte)(oneMinusX * c1 + fractionX * c2); b2 = (byte)(oneMinusX * c3 + fractionX * c4); return (byte)(oneMinusY * b1 + fractionY * b2); }); newPixels[dstOffset + 0] = function(0); newPixels[dstOffset + 1] = function(1); newPixels[dstOffset + 2] = function(2); newPixels[dstOffset + 3] = 255; } } target.SetPixels(width, height, newPixels); }
/// <inheritdoc/> protected override void OnApply(ImageBase <TColor, TPacked> source, Rectangle sourceRectangle) { float[][] kernelX = this.KernelXY; int kernelLength = kernelX.GetLength(0); int radius = kernelLength >> 1; int startY = sourceRectangle.Y; int endY = sourceRectangle.Bottom; int startX = sourceRectangle.X; int endX = sourceRectangle.Right; int maxY = endY - 1; int maxX = endX - 1; TColor[] target = new TColor[source.Width * source.Height]; using (PixelAccessor <TColor, TPacked> sourcePixels = source.Lock()) using (PixelAccessor <TColor, TPacked> targetPixels = target.Lock <TColor, TPacked>(source.Width, source.Height)) { Parallel.For( startY, endY, this.ParallelOptions, y => { for (int x = startX; x < endX; x++) { float rX = 0; float gX = 0; float bX = 0; // Apply each matrix multiplier to the color components for each pixel. for (int fy = 0; fy < kernelLength; fy++) { int fyr = fy - radius; int offsetY = y + fyr; offsetY = offsetY.Clamp(0, maxY); for (int fx = 0; fx < kernelLength; fx++) { int fxr = fx - radius; int offsetX = x + fxr; offsetX = offsetX.Clamp(0, maxX); Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4(); float r = currentColor.X; float g = currentColor.Y; float b = currentColor.Z; rX += kernelX[fy][fx] * r; gX += kernelX[fy][fx] * g; bX += kernelX[fy][fx] * b; } } float red = rX; float green = gX; float blue = bX; TColor packed = default(TColor); packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); targetPixels[x, y] = packed; } }); } source.SetPixels(source.Width, source.Height, target); }