private void ProcessPlane(ImagePlane inputPlane, ImagePlane newPlane, ProcessingBounds bounds) { if (inputPlane.TryGetLinearAccess(out LinearAccessData inputData)) { if (newPlane.TryGetLinearAccess(out LinearAccessData newData)) { var inputYInc = (int)inputData.YInc; var inputXInc = (int)inputData.XInc; var newYInc = (int)newData.YInc; var newXInc = (int)newData.XInc; int boundsY = bounds.StartY + bounds.Height; int boundsX = bounds.StartX + bounds.Width; unsafe { var inputPBase = (byte *)inputData.BasePtr; var newPBase = (byte *)newData.BasePtr; for (int y = bounds.StartY; y < boundsY; y++) { byte *inputPLine = inputPBase + inputYInc * y; byte *newPLine; int newY = y + ShiftY; if (newY < boundsY) { newPLine = newPBase + newYInc * newY; } else if (Wrap) { newPLine = newPBase + newYInc * (newY - boundsY); } else { continue; } for (int x = bounds.StartX; x < boundsX; x++) { byte *inputPPixel = inputPLine + inputXInc * x; byte *newPPixel; int newX = x + ShiftX; if (newX < boundsX) { newPPixel = newPLine + newXInc * newX; } else if (Wrap) { newPPixel = newPLine + newXInc * (newX - boundsX); } else { continue; } if (PixelFilter.Check(*inputPPixel, y * boundsY + x)) { *newPPixel = *inputPPixel; } } } } } else { throw new ArgumentException("New plane could not be accessed linear"); } } else { throw new ArgumentException("Input plane could not be accessed linear"); } }
/// <summary> /// Processes the <paramref name="inputImage"/>. /// </summary> /// <param name="inputImage">Image to process.</param> /// <returns>Processed image.</returns> public Image Process(Image inputImage) { if (inputImage == null) { throw new ArgumentNullException(nameof(inputImage)); } if (inputImage.Planes[PlaneIndex].TryGetLinearAccess(out LinearAccessData inputData)) { double midPointY = inputImage.Height / 2; double midPointX = inputImage.Width / 2; int height = inputImage.Height; int width = inputImage.Width; double cos = System.Math.Cos(Angle.Rad); double sin = System.Math.Sin(Angle.Rad); Image rotatedImage; if (FitImage) { var newHeight = System.Math.Abs(width * sin) + System.Math.Abs(height * cos); var newWidth = System.Math.Abs(width * cos) + System.Math.Abs(height * sin); rotatedImage = new Image((int)newWidth, (int)newHeight, inputImage.Planes.Count); } else { rotatedImage = new Image(inputImage.Size, inputImage.Planes.Count); } for (int i = 0; i < inputImage.Planes.Count; i++) { if (i != PlaneIndex) { inputImage.Planes[i].CopyTo(rotatedImage.Planes[i]); } else { rotatedImage.Planes[i].Initialize(FillValue); } } int offsetX = (int)((rotatedImage.Width / 2) - midPointX); int offsetY = (int)((rotatedImage.Height / 2) - midPointY); var rotatedData = rotatedImage.Planes[PlaneIndex].GetLinearAccess(); int inputYInc = (int)inputData.YInc; int inputXInc = (int)inputData.XInc; int rotatedYInc = (int)rotatedData.YInc; int rotatedXInc = (int)rotatedData.XInc; var rotatedWidth = rotatedImage.Width; var rotatedHeight = rotatedImage.Height; unsafe { byte *pBaseIn = (byte *)inputData.BasePtr; byte *pBaseRo = (byte *)rotatedData.BasePtr; for (int y = 0; y < height; y++) { byte *inputPLine = pBaseIn + inputYInc * y; for (int x = 0; x < width; x++) { byte *inputPPixel = inputPLine + inputXInc * x; var newP = RotatePoint(x, y, midPointX, midPointY, cos, sin, offsetX, offsetY); if (FitImage) { if (PixelFilter.Check(*inputPPixel, y * height + x) && newP.X < rotatedWidth && newP.Y < rotatedHeight) { byte *rotatedPPixel = pBaseRo + rotatedYInc * newP.Y + rotatedXInc * newP.X; * rotatedPPixel = *inputPPixel; } } else if (newP.X < width && newP.X >= 0 && newP.Y < height && newP.Y >= 0 && PixelFilter.Check(*inputPPixel, y * height + x)) { byte *rotatedPPixel = pBaseRo + rotatedYInc * newP.Y + rotatedXInc * newP.X; * rotatedPPixel = *inputPPixel; } } } } return(rotatedImage); } else { throw new ArgumentException("Input image could not be accessed linearly", nameof(inputImage)); } }