using System; using System.Drawing; using System.Drawing.Imaging; using AForge.Math; namespace AForge.Imaging; public class ComplexImage : ICloneable { private Complex[,] data; private int width; private int height; private bool fourierTransformed; public int Width => width; public int Height => height; public bool FourierTransformed => fourierTransformed; public Complex[,] Data => data; protected ComplexImage(int width, int height) { this.width = width; this.height = height; data = new Complex[height, width]; fourierTransformed = false; } public object Clone() { ComplexImage complexImage = new ComplexImage(width, height); Complex[,] array = complexImage.data; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { ref Complex reference = ref array[i, j]; reference = data[i, j]; } } complexImage.fourierTransformed = fourierTransformed; return complexImage; } public static ComplexImage FromBitmap(Bitmap image) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)((Image)image).PixelFormat != 198659) { throw new UnsupportedImageFormatException("Source image can be graysclae (8bpp indexed) image only."); } BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, (PixelFormat)198659); try { return FromBitmap(val); } finally { image.UnlockBits(val); } } public unsafe static ComplexImage FromBitmap(BitmapData imageData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)imageData.PixelFormat != 198659) { throw new UnsupportedImageFormatException("Source image can be graysclae (8bpp indexed) image only."); } int num = imageData.Width; int num2 = imageData.Height; int num3 = imageData.Stride - num; if (!Tools.IsPowerOf2(num) || !Tools.IsPowerOf2(num2)) { throw new InvalidImagePropertiesException("Image width and height should be power of 2."); } ComplexImage complexImage = new ComplexImage(num, num2); Complex[,] array = complexImage.data; byte* ptr = (byte*)imageData.Scan0.ToPointer(); for (int i = 0; i < num2; i++) { int num4 = 0; while (num4 < num) { array[i, num4].Re = (float)(int)(*ptr) / 255f; num4++; ptr++; } ptr += num3; } return complexImage; } public unsafe Bitmap ToBitmap() { Bitmap val = Image.CreateGrayscaleImage(width, height); BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, (PixelFormat)198659); int num = val2.Stride - width; double num2 = (fourierTransformed ? System.Math.Sqrt(width * height) : 1.0); byte* ptr = (byte*)val2.Scan0.ToPointer(); for (int i = 0; i < height; i++) { int num3 = 0; while (num3 < width) { *ptr = (byte)System.Math.Max(0.0, System.Math.Min(255.0, data[i, num3].Magnitude * num2 * 255.0)); num3++; ptr++; } ptr += num; } val.UnlockBits(val2); return val; } public void ForwardFourierTransform() { if (fourierTransformed) { return; } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (((j + i) & 1) != 0) { data[i, j].Re *= -1.0; data[i, j].Im *= -1.0; } } } FourierTransform.FFT2(data, FourierTransform.Direction.Forward); fourierTransformed = true; } public void BackwardFourierTransform() { if (!fourierTransformed) { return; } FourierTransform.FFT2(data, FourierTransform.Direction.Backward); fourierTransformed = false; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (((j + i) & 1) != 0) { data[i, j].Re *= -1.0; data[i, j].Im *= -1.0; } } } } }