private void FilterPixelsBilinear(FastBitmap source, FastBitmap destination, int width, int height, Int32Rect transformedSpace) { int srcWidth = width; int srcHeight = height; int srcWidth1 = width - 1; int srcHeight1 = height - 1; int outWidth = transformedSpace.Width; int outHeight = transformedSpace.Height; int outX = transformedSpace.X; int outY = transformedSpace.Y; for (int y = 0; y < outHeight; y++) { for (int x = 0; x < outWidth; x++) { Point output = TransformInverse(outX + x, outY + y); int srcX = (int)Math.Floor(output.X); int srcY = (int)Math.Floor(output.Y); double xWeight = output.X - srcX; double yWeight = output.Y - srcY; Color nw, ne, sw, se; if (srcX >= 0 && srcX < srcWidth1 && srcY >= 0 && srcY < srcHeight1) { // Easy case, all corners are in the image nw = source[srcX, srcY]; ne = source[srcX + 1, srcY]; sw = source[srcX, srcY + 1]; se = source[srcX + 1, srcY + 1]; } else { // Some of the corners are off the image nw = GetPixel(source, srcX, srcY, srcWidth, srcHeight); ne = GetPixel(source, srcX + 1, srcY, srcWidth, srcHeight); sw = GetPixel(source, srcX, srcY + 1, srcWidth, srcHeight); se = GetPixel(source, srcX + 1, srcY + 1, srcWidth, srcHeight); } destination[x, y] = ImageMath.BilinearInterpolate(xWeight, yWeight, nw, ne, sw, se); } } }
private Color GetPixel(FastBitmap bitmap, int x, int y, int width, int height) { if (x < 0 || x >= width || y < 0 || y >= height) { switch (EdgeAction) { case EdgeAction.Wrap: return(bitmap[ImageMath.Mod(x, width), ImageMath.Mod(y, height)]); case EdgeAction.Clamp: return(bitmap[ImageMath.Clamp(x, 0, width - 1), ImageMath.Clamp(y, 0, height - 1)]); case EdgeAction.RgbClamp: { Color edgeColour = bitmap[ImageMath.Clamp(x, 0, width - 1), ImageMath.Clamp(y, 0, height - 1)]; return(Color.FromArgb(0, edgeColour.R, edgeColour.G, edgeColour.B)); } case EdgeAction.Zero: return(Colors.Transparent); } } return(bitmap[x, y]); }