/// <summary> /// 辐射定标。 /// </summary> /// <param name="InputDS">输入的栅格数据集。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="Gain">增益倍数。</param> /// <param name="Offset">偏移量。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>返回操作成功或失败。</returns> public static bool ApplyGainAndOffset(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.DataType OutDataType, List <double> Gain, List <double> Offset, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if ((Gain.Count != InputDS.RasterCount) || (Offset.Count != InputDS.RasterCount)) { throw new IndexOutOfRangeException("增益数据或偏移数据与输入数据集波段数不符。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } FrmProgress FP = new FrmProgress() { Text = "正在进行辐射定标...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, InputDS.RasterCount, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int i = 0; i < InputDS.RasterCount; i++) //遍历每个波段 { FP.SetProgress2("正在处理波段:", i + 1, InputDS.RasterCount, ""); for (int Row = 0; Row < ySize; Row++) //遍历每一行(y) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; //读取DN到数组 InputDS.GetRasterBand(i + 1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) //对每一个值进行计算 { Values[Col] = GainOffset(Values[Col], Gain[i], Offset[i]); } //写结果到新栅格 DS.GetRasterBand(i + 1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 重分类。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="ReplaceList">用于对照值替换的表。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出数据集的路径。</param> /// <param name="DefaultValue">若值不在ReplaceList中,则该像元的值设为。</param> /// <returns>操作成功或失败。</returns> public static bool Reclassify(OSGeo.GDAL.Dataset InputDS, List <double[]> ReplaceList, OSGeo.GDAL.DataType OutDataType, string OutPath, double DefaultValue = 0.03) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if (InputDS.RasterCount != 1) { throw new ArgumentOutOfRangeException("重分类的影像不是灰度影像。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行重分类...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); double NoDataValue = -9999; int HasNoDataValue = -1; InputDS.GetRasterBand(1).GetNoDataValue(out NoDataValue, out HasNoDataValue); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); if (HasNoDataValue == 1) { DS.GetRasterBand(1).SetNoDataValue(NoDataValue); } Tools.Common.CopyMetadata(InputDS, DS); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //值为NoData if (Math.Abs(Values[Col] - NoDataValue) < 1e-7) { continue; } int i = -1; //对照表进行值替换 for (i = 0; i < ReplaceList.Count; i++) { if (Values[Col] == ReplaceList[i][0]) { Values[Col] = ReplaceList[i][1]; break; } } if (i == ReplaceList.Count) { Values[Col] = 0.03; } } DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } DS.Dispose(); FP.Finish(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// NoData值替换。将非NoData值替换为指定值。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="NoDataValue">NoData值。</param> /// <param name="ReplaceValue">非NoData值替换为的值。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出数据集的路径。</param> /// <returns>操作成功或失败。</returns> public static bool ReplaceNoData(OSGeo.GDAL.Dataset InputDS, double NoDataValue, double ReplaceValue, OSGeo.GDAL.DataType OutDataType, string OutPath, double NewNoDataValue = -9999) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if (InputDS.RasterCount != 1) { throw new ArgumentOutOfRangeException("替换值的影像不是灰度影像。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行非NoData值替换...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); DS.GetRasterBand(1).SetNoDataValue(NoDataValue); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { if (Math.Abs(Values[Col] - NoDataValue) > 1e-7) { //将ReplaceValue与NoDataValue的值设置为一样的可以仅更改NoData值 if (Math.Abs(ReplaceValue - NoDataValue) > 1e-7) { Values[Col] = ReplaceValue; } } else { Values[Col] = NewNoDataValue; } } DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } DS.Dispose(); FP.Finish(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
public static bool CutImage(OSGeo.GDAL.Dataset InputDS, int CutWidth, int CutHeight, OSGeo.GDAL.DataType OutDataType, string OutFolder) { try { if (InputDS == null) { throw new ArgumentNullException("输入的数据集不可为空。"); } if (String.IsNullOrWhiteSpace(OutFolder)) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } //取输入的宽、高、波段最小值创建输出数据集。 int Width = InputDS.RasterXSize; int Height = InputDS.RasterYSize; int Rows = Height / CutHeight; int Cols = Width / CutWidth; FrmProgress FP = new FrmProgress() { Text = "正在进行影像裁剪...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); FP.Output("输出的目录为:" + OutFolder); FP.Output("输出的数据类型为:" + OutDataType.ToString()); for (int row = 0; row < Rows; row++) { FP.SetProgress2("总进度:", row + 1, Rows, ""); string ParentPath = row.ToString(); Directory.CreateDirectory(Path.Combine(OutFolder, ParentPath)); for (int col = 0; col < Cols; col++) { FP.SetProgress1("当前行进度:", col + 1, Cols, ""); string OutName = row.ToString() + "_" + col.ToString() + ".tif"; OSGeo.GDAL.Dataset DS = Dri.Create(Path.Combine(OutFolder, ParentPath, OutName), CutWidth, CutHeight, InputDS.RasterCount, OutDataType, null); for (int band = 1; band <= InputDS.RasterCount; band++) { double[] buf = new double[CutWidth * CutHeight]; InputDS.GetRasterBand(band).ReadRaster(col * CutWidth, row * CutHeight, CutWidth, CutHeight, buf, CutWidth, CutHeight, 0, 0); DS.GetRasterBand(band).WriteRaster(0, 0, CutWidth, CutHeight, buf, CutWidth, CutHeight, 0, 0); } ////单行读取写入,防止爆内存。 //for (int cRow = 0; cRow < CutHeight; cRow++) //{ // double[] buf = new double[CutWidth]; // InputDS.GetRasterBand(band).ReadRaster(col * CutWidth, row * CutHeight + cRow, CutWidth, 1, buf, CutWidth, 1, 0, 0); // DS.GetRasterBand(band).WriteRaster(0, cRow, CutWidth, 1, buf, CutWidth, 1, 0, 0); // DS.FlushCache(); // Thread.Sleep(1); //} DS.FlushCache(); DS.Dispose(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); InputDS.Dispose(); Dri.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 数据集相除。 /// </summary> /// <param name="D1">被除数据集。</param> /// <param name="D2">除数据集。</param> /// <param name="OutDataType">输出数据集的数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>操作成功或失败。</returns> public static bool Divide(OSGeo.GDAL.Dataset D1, OSGeo.GDAL.Dataset D2, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (D1 == null || D2 == null) { throw new ArgumentNullException("输入的数据集不可为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } //取输入的宽、高、波段最小值创建输出数据集。 int Width = Math.Min(D1.RasterXSize, D2.RasterXSize); int Height = Math.Min(D1.RasterYSize, D2.RasterYSize); int band = Math.Min(D1.RasterCount, D2.RasterCount); FrmProgress FP = new FrmProgress() { Text = "正在进行数据集除法运算...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, Width, Height, band, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(D1, DS); for (int bandcount = 1; bandcount <= band; bandcount++) { FP.SetProgress2("正在处理", bandcount, band, "波段"); for (int row = 0; row < Height; row++) { FP.SetProgress1("正在处理:", row + 1, Height, "行"); double[] d1Tmp = new double[Width]; double[] d2Tmp = new double[Width]; double[] dsTmp = new double[Width]; D1.GetRasterBand(bandcount).ReadRaster(0, row, Width, 1, d1Tmp, Width, 1, 0, 0); D2.GetRasterBand(bandcount).ReadRaster(0, row, Width, 1, d2Tmp, Width, 1, 0, 0); for (long i = 0; i < Width; i++) { if (d2Tmp[i] == 0) { dsTmp[i] = 0; } else { dsTmp[i] = d1Tmp[i] / d2Tmp[i]; } } DS.GetRasterBand(bandcount).WriteRaster(0, row, Width, 1, dsTmp, Width, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 影像直方图匹配。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="MatchDS">要匹配到的数据集。</param> /// <param name="InputCumu">输入的数据集的累积概率表。</param> /// <param name="MatchingCumu">要匹配到的数据集的累积概率表。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>操作成功或失败。</returns> public static bool HistogramMatching(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.Dataset MatchDS, double[][] InputCumu, double[][] MatchingCumu, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (InputDS.RasterCount != MatchDS.RasterCount) { throw new ArgumentException("数据集波段数不一致。"); } FrmProgress FP = new FrmProgress() { Text = "正在进行影像直方图匹配...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); int[][] LUT = new int[InputDS.RasterCount][]; FP.Output("正在计算查找表..."); for (int i = 0; i < InputDS.RasterCount; i++) { LUT[i] = HistogramMatching(InputCumu[i], MatchingCumu[i]); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, InputDS.RasterCount, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int bandcount = 0; bandcount < InputDS.RasterCount; bandcount++) { FP.SetProgress2("正在处理", bandcount + 1, InputDS.RasterCount, "波段"); Tools.Common.GetMinimum(InputDS.GetRasterBand(bandcount + 1), out double inputDSBandMin); Tools.Common.GetMinimum(MatchDS.GetRasterBand(bandcount + 1), out double matchDSBandMin); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理", Row + 1, ySize, "行"); double[] Values = new double[xSize]; //读取DN到数组 InputDS.GetRasterBand(bandcount + 1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //防止GDAL自带方法算出的统计数据越界。 if ((Values[Col] - inputDSBandMin) <= 0) { Values[Col] = matchDSBandMin + LUT[bandcount][0]; continue; } if ((Values[Col] - inputDSBandMin) >= LUT[bandcount].Length - 1) { Values[Col] = matchDSBandMin + LUT[bandcount][LUT[bandcount].Length - 1]; continue; } Values[Col] = matchDSBandMin + LUT[bandcount][(int)(Values[Col] - inputDSBandMin)]; } //写结果到新栅格 DS.GetRasterBand(bandcount + 1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 平滑锐化算法。 /// </summary> /// <param name="InputDS">输入的栅格数据集。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="Method">平滑锐化方法。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>返回操作成功或失败。</returns> public static bool SmoothSharpening(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.DataType OutDataType, SmoothShapeninngMethods Method, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行平滑锐化操作...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); FP.Output("选择的平滑/锐化方法为:\"" + (typeof(SmoothShapeninngMethods).GetField((Method).ToString()).GetCustomAttributes(false)[0] as DescriptionAttribute).Description + "\""); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, InputDS.RasterCount, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int band = 0; band < InputDS.RasterCount; band++) //遍历每个波段 { FP.SetProgress1("正在处理", band + 1, InputDS.RasterCount, "波段"); for (int Row = 0; Row < ySize - 2; Row++) //从第1行遍历至倒数第三行 { FP.SetProgress2("正在处理", Row, ySize - 2, "行"); double[] Values = new double[3 * xSize]; //读取的数值 double[] Result = new double[xSize]; //结果数值 InputDS.GetRasterBand(band + 1).ReadRaster(0, Row, xSize, 3, Values, xSize, 3, 0, 0); //读取3行 Array.Copy(Values, xSize, Result, 0, xSize); // for (int Col = 0; Col < xSize - 2; Col++) //对每一个值进行计算 { double[,] Input = new double[3, 3]; for (int i = 0; i < 3; i++) { Input[i, 0] = Values[Col + i * xSize]; Input[i, 1] = Values[Col + i * xSize + 1]; Input[i, 2] = Values[Col + i * xSize + 2]; } Result[Col + 1] = SmoothSharpening(Input, Method); //计算输入数据中心像元的值 } //写结果到新栅格 DS.GetRasterBand(band + 1).WriteRaster(0, Row + 1, xSize, 1, Result, xSize, 1, 0, 0); } if ((Method.ToString()).Contains("Smooth")) { double[] row = new double[xSize]; InputDS.GetRasterBand(band + 1).ReadRaster(0, 0, xSize, 1, row, xSize, 1, 0, 0); //读取第一行 DS.GetRasterBand(band + 1).WriteRaster(0, 0, xSize, 1, row, xSize, 1, 0, 0); InputDS.GetRasterBand(band + 1).ReadRaster(0, ySize - 1, xSize, 1, row, xSize, 1, 0, 0); //读取最后一行 DS.GetRasterBand(band + 1).WriteRaster(0, ySize - 1, xSize, 1, row, xSize, 1, 0, 0); } DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 二值化。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="Threshold">分割阈值。</param> /// <param name="ZeroValue">小于阈值的像元值被设为...</param> /// <param name="OneValue">大于阈值的像元值被设为...</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>操作成功或失败。</returns> public static bool Binarize(OSGeo.GDAL.Dataset InputDS, double Threshold, double ZeroValue, double OneValue, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (InputDS.RasterCount != 1) { throw new ArgumentException("输入的数据集波段大于1。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行二值化操作...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //阈值应用 if (Values[Col] < Threshold) { Values[Col] = ZeroValue; } else { Values[Col] = OneValue; } } DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.Message); return(false); } }