/// <summary> /// Bilinearly Interpolate the filtered image to keep visual smoothness and avoid edgy effect /// </summary> private IImageAdapter Interp(IImageAdapter iiad) { ImageAdapter retVal = new ImageAdapter(iiad); int llLength = (int)Math.Pow(2, Level); double wexpFactor = (double)(iiad.Width - 4 * Level) / ((iiad.Width) * llLength); double hexpFactor = (double)(iiad.Height - 4 * Level) / ((iiad.Height) * llLength); for (int j = 0; j < iiad.Height; j++) { for (int i = 0; i < iiad.Width; i++) { double x = (double)i * wexpFactor; double y = (double)j * hexpFactor; retVal[i, j] = BilinearInterpolator.ProcessPoint(x, y, iiad, null); } } return(retVal); }
/// <summary> /// Apply the transform using the supplied matrix /// </summary> /// <param name="matrix">the matrix to be applied (format if x1,y1,x2,y2,t1,t2)</param> public void Transform(Matrix2D matrix) { if (_imageSource == null) { throw new RenderingVerificationException("ImageSource not Assigned, cannot transform a unknow image"); } if (matrix == null) { throw new ArgumentException("Invalid argument passed in, must be a valid instance (not set to null) of Matrix2D or an array of double of length " + Matrix2D.Length); } if (matrix.IsInvertible == false) { throw new Matrix2DException("Matrix passed in is not inversible, cannot transform using this matrix (matrix passed in : )" + matrix.ToString()); } if (matrix.IsIdentity) { _imageTransformed = (IImageAdapter)_imageSource.Clone(); return; } // Create the IImageAdapter to return int width = _imageSource.Width; int height = _imageSource.Height; if (_resizeToFitOutputImage) { double x = 0.0; double y = 0.0; Point topLeft = new Point((int)(x + Math.Sign(x) * 0.5), (int)(y + Math.Sign(y) * 0.5)); x = matrix.X1 * width; y = matrix.X2 * width; Point topRight = new Point((int)(x + Math.Sign(x) * 0.5), (int)(y + Math.Sign(y) * 0.5)); x = matrix.X1 * width + matrix.Y1 * height; y = matrix.X2 * width + matrix.Y2 * height; Point bottomRight = new Point((int)(x + Math.Sign(x) * 0.5), (int)(y + Math.Sign(y) * 0.5)); x = matrix.Y1 * height; y = matrix.Y2 * height; Point bottomLeft = new Point((int)(x + Math.Sign(x) * 0.5), (int)(y + Math.Sign(y) * 0.5)); width = (int)Math.Max(Math.Abs(bottomRight.X - topLeft.X), Math.Abs(topRight.X - bottomLeft.X)); height = (int)Math.Max(Math.Abs(bottomRight.Y - topLeft.Y), Math.Abs(topRight.Y - bottomLeft.Y)); } _imageTransformed = new ImageAdapter(width, height, _unassignedColor); // Scale down imnage if needed (average pixels) // double horizontalScaling = double.NaN; if (matrix.X1 != 0) { horizontalScaling = Math.Sqrt(Math.Abs(matrix.Determinant * matrix.Y2 / matrix.X1)); } else { horizontalScaling = Math.Sqrt(Math.Abs(matrix.Determinant * matrix.Y1 / matrix.X2)); } double verticalScaling = Math.Sqrt(matrix.Determinant / horizontalScaling); IImageAdapter scaledImage = BilinearInterpolator.ScaleDown(horizontalScaling, verticalScaling, _imageSource); // Interpolate image (if scaling up and/or rotation applied to image) for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { double ix = 0.0; double iy = 0.0; ConvertCoordinates(matrix, x, y, out ix, out iy); _imageTransformed[x, y] = _interpolationMethod(ix, iy, scaledImage, _unassignedColor); } } }