public static unsafe SKPixmap ToSKPixmap(this ComplexImage complexImage, SKImage image) { SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; Complex[,] data = complexImage.Data; double scale = (complexImage.IsFourierTransformed) ? Math.Sqrt(width * height) : 1; bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { // Assuming SKColorType.Rgba8888 - used by iOS and Android // (UWP uses SKColorType.Bgra8888) byte result = (byte)Math.Max(0, Math.Min(255, data[row, col].Magnitude * scale * 255)); * bmpPtr++ = result; // red * bmpPtr++ = result; // green * bmpPtr++ = result; // blue bmpPtr += 1; // Ignore alpha } } return(pixmap); }
static unsafe ComplexImage ToComplexImage(this SKImage image) { SKPixmap pixmap = image.PeekPixels(); byte * bmpPtr = (byte *)pixmap.GetPixels().ToPointer(); int width = image.Width; int height = image.Height; if ((!MathHelpers.IsPowerOf2(width)) || (!MathHelpers.IsPowerOf2(height))) { throw new ArgumentException("Image width and height must be a power of 2."); } ComplexImage complexImage = new ComplexImage(width, height); Complex[,] data = complexImage.Data; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { byte red = *bmpPtr++; byte green = *bmpPtr++; byte blue = *bmpPtr++; bmpPtr += 1; // Ignore alpha // Assuming SKColorType.Rgba8888 - used by iOS and Android // (UWP uses SKColorType.Bgra8888) byte result = (byte)(0.2126 * red + 0.7152 * green + 0.0722 * blue); data[row, col].Re = (float)result / 255; } } return(complexImage); }
public void Apply(ComplexImage complexImage) { if (!complexImage.IsFourierTransformed) { throw new ArgumentException("The source complex image should be Fourier transformed."); } int width = complexImage.Width; int height = complexImage.Height; int halfWidth = width >> 1; int halfHeight = height >> 1; int min = frequencyRange.Min; int max = frequencyRange.Max; Complex[,] data = complexImage.Data; for (int i = 0; i < height; i++) { int y = i - halfHeight; for (int j = 0; j < width; j++) { int x = j - halfWidth; int d = (int)Math.Sqrt(x * x + y * y); if ((d > max) || (d < min)) { data[i, j].Re = 0; data[i, j].Im = 0; } } } }
public static unsafe SKPixmap FrequencyFilter(this SKImage image, int min, int max) { ComplexImage complexImage = image.ToComplexImage(); complexImage.FastFourierTransform(); FrequencyFilter filter = new FrequencyFilter(new FrequencyRange(min, max)); filter.Apply(complexImage); complexImage.ReverseFastFourierTransform(); SKPixmap pixmap = complexImage.ToSKPixmap(image); return(pixmap); }