/// <summary> /// Will convolve the 2-D filter with the source image, producing the output image. /// This overload assumes that you are working with files. /// </summary> /// <param name="SourceFile">A string representing the image file to open.</param> /// <param name="DestFile">A string representing the image file to save to.</param> /// <param name="filter">A 2D array of floats, row major. Filter must be smaller than image.</param> /// <param name="ShowProgressDialog">Boolean, true to have the function automatically show a dialog.</param> /// <param name="ICallBack">A MapWinGIS.ICallback for handling errors and progress messages</param> /// <returns>Boolean, false if the process was canceled.</returns> public static bool ApplyFilter(string SourceFile, string DestFile, float[,] filter, bool ShowProgressDialog, MapWinGIS.ICallback ICallBack) { MapWinUtility.Logger.Dbg("ApplyFilter(SourceFile: " + SourceFile + ",\n" + " DestFile: " + DestFile + ",\n" + " filter: [" + filter.GetUpperBound(0) + ", " + filter.GetUpperBound(1) + "],\n" + " ShowProgressDialog: " + ShowProgressDialog.ToString() + ",\n" + " ICallback)"); bool res; // Argument checks if (SourceFile == null) { MapWinUtility.Logger.Dbg("Argument Exception: SourceFile cannot be null."); throw new ArgumentException("SourceFile cannot be null."); } if (System.IO.File.Exists(SourceFile) == false) { MapWinUtility.Logger.Dbg("Argument Exception: SourceFile not found."); throw new ArgumentException("SourceFile not found."); } if (DestFile == null) { MapWinUtility.Logger.Dbg("Argument Exception: DestFile cannot be null."); throw new ArgumentException("DestFile cannot be null."); } if (System.IO.File.Exists(SourceFile) == true) { System.IO.File.Delete(DestFile); } if (filter.GetUpperBound(0) == 0 || filter.GetUpperBound(1) == 0) { MapWinUtility.Logger.Dbg("Argument Exception: Filter must have values."); throw new ArgumentException("Filter must have values."); } // Check image object MapWinGIS.Image SourceImage = new MapWinGIS.Image(); res = SourceImage.Open(SourceFile, MapWinGIS.ImageType.USE_FILE_EXTENSION, true, null); if (res == false) { MapWinUtility.Logger.Dbg("Application Exception: " + "Attempting to open " + SourceFile + " produced the following error:\n" + SourceImage.get_ErrorMsg(SourceImage.LastErrorCode)); throw new ApplicationException("Attempting to open " + SourceFile + " produced the following error:\n" + SourceImage.get_ErrorMsg(SourceImage.LastErrorCode)); } // Try to create the output image MapWinGIS.Image DestImage = new MapWinGIS.Image(); res = DestImage.CreateNew(SourceImage.Width, SourceImage.Height); if (res == false) { MapWinUtility.Logger.Dbg("Application Exception: " + "Attempting to create " + DestFile + " produced the following error:\n" + DestImage.get_ErrorMsg(DestImage.LastErrorCode)); throw new ApplicationException("Attempting to create " + DestFile + " produced the following error:\n" + DestImage.get_ErrorMsg(DestImage.LastErrorCode)); } DestImage.Save(DestFile, false, MapWinGIS.ImageType.USE_FILE_EXTENSION, ICallBack); res = Do_ApplyFilter(SourceImage, ref DestImage, filter, ShowProgressDialog, ICallBack); DestImage.Close(); SourceImage.Close(); MapWinUtility.Logger.Dbg("Finished ApplyFilter"); return(res); }
// False if the user canceled, true otherwise private static bool Do_ApplyFilter(MapWinGIS.Image SourceImage, ref MapWinGIS.Image DestImage, float[,] filter, bool ShowProgressDialog, MapWinGIS.ICallback ICallBack) { int Prog = 0; int OldProg = 0; // Report unnamed as differently from null string SourceFile = "null"; string DestFile = "null"; if (SourceImage != null) { SourceFile = SourceImage.Filename; if (SourceFile == null) { SourceFile = "Unnamed"; } } else { MapWinUtility.Logger.Dbg("Argument Exception: SourceImage cannot be null."); throw new ArgumentException("SourceImage cannot be null."); } if (DestImage != null) { DestFile = SourceImage.Filename; if (DestFile == null) { DestFile = "Unnamed"; } } else { MapWinUtility.Logger.Dbg("Argument Exception: DestImage cannot be null."); throw new ArgumentException("DestImage cannot be null."); } MapWinUtility.Logger.Dbg("Do_ApplyFilter(SourceImage: " + SourceImage.Filename + ",\n" + " DestImage: " + DestImage.Filename + ",\n" + " filter: [" + filter.GetUpperBound(0) + ", " + filter.GetUpperBound(1) + "],\n" + " ShowProgressDialog: " + ShowProgressDialog.ToString() + ",\n" + " ICallback)"); ProgressDialog MyProgress = new ProgressDialog(); if (filter.GetUpperBound(0) == 0 || filter.GetUpperBound(1) == 0) { MapWinUtility.Logger.Dbg("Argument Exception: Filter must have values."); throw new ArgumentException("Filter must have values."); } // Ensure the filter is smaller than the image. if (filter.GetUpperBound(0) > SourceImage.Height || filter.GetUpperBound(1) > SourceImage.Width) { throw new ArgumentException("The filter is too large for this image. In order for convolution to work, the image must be larger than the filter."); } // We are going to assume mirror handling of edges ExtHandler LocHandler = new ExtHandler(SourceImage.Height, SourceImage.Width); // convolve int R, G, B, color; int Xcor = 0, Ycor = 0; // Corrected X and Y locations to take into account mirror int fH, fW; // stores the values of half the height and width of the filter fH = (int)filter.GetUpperBound(0) / 2; fW = (int)filter.GetUpperBound(1) / 2; if (ICallBack == null) { MyProgress.Show(); MyProgress.WriteMessage("Applying Filter..."); MapWinUtility.Logger.Progress("Applying Filter...", Prog, OldProg); } for (int row = 0; row < SourceImage.Height; row++) { for (int col = 0; col < SourceImage.Width; col++) { float fR = 0; float fG = 0; float fB = 0; for (int Y = 0; Y <= filter.GetUpperBound(0); Y++) { for (int X = 0; X <= filter.GetUpperBound(1); X++) { // Read the color for this spot LocHandler.CorrectLocation(col + X - fW, row + Y - fH, ref Xcor, ref Ycor); color = SourceImage.get_Value(Ycor, Xcor); R = color % 256; G = (int)(color / 256) % 256; B = (int)(color / (256 * 256)); // convolve the values with the filter and add them to the accumulators fR += filter[Y, X] * R; fG += filter[Y, X] * G; fB += filter[Y, X] * B; } } // After convolution, write the combined value to the file R = (int)fR; if (R > 255) { R = 255; } G = (int)fG; if (G > 255) { G = 255; } B = (int)fB; if (B > 255) { B = 255; } color = (256 * 256) * B + 256 * G + R; DestImage.set_Value(row, col, color); } Prog = (100 * row) / SourceImage.Height; if (Prog > OldProg) { if (ICallBack != null) { ICallBack.Progress("Status", Prog, "Filtering Image..."); } if (ShowProgressDialog == true) { MyProgress.Progress = Prog; if (MyProgress.IsCanceled == true) { MapWinUtility.Logger.Message("Apply Filter was canceled.", "Process Canceled", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information, System.Windows.Forms.DialogResult.OK); return(false); } } MapWinUtility.Logger.Progress("Filtering Image..." + Prog.ToString() + "%Complete", Prog, OldProg); OldProg = Prog; } } MyProgress.Hide(); DestImage.dX = SourceImage.dX; DestImage.dY = SourceImage.dY; DestImage.SetProjection(SourceImage.GetProjection()); DestImage.Save(DestImage.Filename, true, MapWinGIS.ImageType.USE_FILE_EXTENSION, null); MapWinUtility.Logger.Dbg("Finsihed ApplyFilter"); return(true); }
/// <summary> /// Reprojects an image using the currently defined projective transform. /// Be sure to call Derive_Coefficients first. This loops through point by point /// so won't be very fast. /// </summary> /// <param name="SourceImage">A MapWinGIS.Image object to be transformed</param> /// <param name="resultImage">A string representing the destination filename</param> /// <param name="ICallBack">A MapWinGIS.ICallback interface for progress messages</param> /// <remarks>ArgumentExceptions should be trapped for user error, but other types should be reported as bugs</remarks> public void ProjectImage(MapWinGIS.Image SourceImage, string resultImage, MapWinGIS.ICallback ICallBack) { bool res; if (SourceImage == null) { throw new ArgumentException("Source Image cannot be null."); } if (resultImage == null) { resultImage = System.IO.Path.ChangeExtension(SourceImage.Filename, "_Projected" + System.IO.Path.GetExtension(SourceImage.Filename)); } if (Defined == false) { throw new ApplicationException("You first have to define the coefficients by calling Derive_Coefficients."); } MapWinGIS.Image DestImage = new MapWinGIS.Image(); try { res = DestImage.CreateNew(m_OutputWidth, m_OutputHeight); } catch { throw new ApplicationException("The current Image object crashes with images too large to fit in memory."); } if (res == false) { throw new ApplicationException("Application Exception when Creating New: " + DestImage.get_ErrorMsg(DestImage.LastErrorCode)); } if (res == false) { throw new ApplicationException("Image object is having trouble creating a new image."); } for (int Yprj = 0; Yprj < m_OutputHeight; Yprj++) { for (int Xprj = 0; Xprj < m_OutputWidth; Xprj++) { double X, Y; double X1, Y1; int Xorig = 0; int Yorig = 0; X1 = (double)Xprj; Y1 = (double)Yprj; X = -(b * Y1 - Y1 * h * c + e * c - X1 * e + f * X1 * h - f * b) / (X1 * h * d + b * Y1 * g - b * d - X1 * g * e + a * e - a * Y1 * h); Y = -(c * Y1 * g + X1 * d - a * Y1 - X1 * g * f - c * d + a * f) / (X1 * h * d + b * Y1 * g - b * d - X1 * g * e + a * e - a * Y1 * h); if (X < 0 || Y < 0 || X > m_InputWidth || Y > m_InputHeight) { continue; } // using nearest neighbors Xorig = rnd(X); Yorig = rnd(Y); int Rowo = (m_InputHeight - 1) - Yorig; int pVal = SourceImage.get_Value(Rowo, Xorig); int row = (m_OutputHeight - 1) - Yprj; DestImage.set_Value(row, Xprj, pVal); } if (ICallBack != null) { ICallBack.Progress("Status", (Yprj * 100) / m_OutputHeight, "Row: " + Yprj.ToString()); } } DestImage.dX = m_OutputCellWidth; DestImage.dY = m_OutputCellHeight; DestImage.XllCenter = m_XllCenter; DestImage.YllCenter = m_YllCenter; string dir = System.IO.Path.GetDirectoryName(resultImage); if (!System.IO.Directory.Exists(dir)) { System.IO.Directory.CreateDirectory(dir); } if (System.IO.Path.GetExtension(resultImage) == ".jpg") { resultImage = System.IO.Path.ChangeExtension(resultImage, ".bmp"); } res = DestImage.Save(resultImage, true, MapWinGIS.ImageType.USE_FILE_EXTENSION, ICallBack); if (res == false) { throw new ApplicationException(DestImage.get_ErrorMsg(DestImage.LastErrorCode)); } DestImage.SetProjection(SourceImage.GetProjection()); DestImage.Close(); if (ICallBack != null) { ICallBack.Progress("Status", 0, "Saved output as " + DestImage.Filename); } }