环境:VS2010,C#,GDAL1.7
读取影像:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Diagnostics; 10 using System.Drawing.Imaging; 11 using OSGeo.GDAL; 12 using AppScene; 13 14 namespace GdalReader 15 { 16 public partial class Form1 : Form 17 { 18 public Form1() 19 { 20 InitializeComponent(); 21 } 22 string __ImagePath = string.Empty; 23 private OSGeo.GDAL.Dataset __Geodataset; 24 private int[] __DisplayBands; 25 private Rectangle __DrawRect; 26 private Bitmap __BitMap; 27 private void btnBrower_Click(object sender, EventArgs e) 28 { 29 OpenFileDialog dlg = new OpenFileDialog(); 30 dlg.Title = ""; 31 dlg.Filter = "Img(*.img)|*.img"; 32 if (dlg.ShowDialog() == DialogResult.OK) 33 { 34 OSGeo.GDAL.Gdal.AllRegister(); 35 __ImagePath = dlg.FileName; 36 txtPath.Text = __ImagePath; 37 OSGeo.GDAL.Dataset dataset = OSGeo.GDAL.Gdal.Open(__ImagePath, OSGeo.GDAL.Access.GA_ReadOnly); 38 __Geodataset = dataset; 39 if (__Geodataset != null) 40 { 41 if (__Geodataset.RasterCount >= 3) 42 __DisplayBands = new int[3] { 1, 2, 3 }; 43 else 44 __DisplayBands = new int[3] { 1, 1, 1 }; 45 } 46 double[] dd = new double[4]; 47 dataset.GetGeoTransform(dd); 48 string prj = dataset.GetProjection(); 49 50 string str = string.Format("波段数目:{0}\n行数:{1};列数:{2}\n坐标参考:{3},{4},{5},{6}\n", __Geodataset.RasterCount, __Geodataset.RasterXSize, __Geodataset.RasterYSize, dd[0], dd[1], dd[2], dd[3]); 51 str += prj + "\n"; 52 for (int i = 1; i <= __Geodataset.RasterCount; ++i) 53 { 54 OSGeo.GDAL.Band band = dataset.GetRasterBand(i); 55 str += "波段" + i + ":" + band.DataType.ToString(); 56 57 } 58 richTextBox1.Text = str; 59 InitialIMG(); 60 SimpleRasterShow simRaster = new SimpleRasterShow(""); 61 simRaster.IsOn = true; 62 simRaster.bitmap = __BitMap; 63 sceneControl1.CurrentWorld.RenderableObjects.ChildObjects.Add(simRaster); 64 } 65 } 66 67 public void InitialIMG() 68 { 69 if (__Geodataset != null) 70 { 71 Rectangle rect = new Rectangle(0, 0, __Geodataset.RasterXSize, __Geodataset.RasterYSize); 72 float width = (float)this.Width; 73 float height = (float)this.Height; 74 RectangleF Extent = ExtRect(rect, width, height); 75 double scale = Extent.Width / this.Width; 76 //double scaley = Extent.Height / this.Height; 77 double bufWidth = __Geodataset.RasterXSize / scale; 78 double bufHeight = __Geodataset.RasterYSize / scale; 79 Debug.WriteLine("Buffered width is:" + bufWidth); 80 Debug.WriteLine("Buffered height is:" + bufHeight); 81 double bufX = (this.Width - bufWidth) / 2.0; 82 double bufY = (this.Height - bufHeight) / 2.0; 83 __DrawRect = new Rectangle((int)bufX, (int)bufY, (int)bufWidth, (int)bufHeight); 84 Rectangle ExtentRect = new Rectangle(0, 0, (int)bufWidth, (int)bufHeight); 85 //__DispRectCenter = new PointF((float)(bufX + bufWidth / 2.0), (float)(bufY + bufHeight / 2.0)); 86 // __Zoom = (float)scale; 87 //__Zoom=(float)(scalex>scaley?scalex:scaley); 88 __BitMap = RSImg2BitMap(__Geodataset, ExtentRect, __DisplayBands); 89 // Invalidate(); 90 } 91 } 92 public RectangleF ExtRect(Rectangle rect, float width, float height) 93 { 94 double midX = rect.X + rect.Width / 2.0; 95 double midY = rect.Y + rect.Height / 2.0; 96 double newh = 0.0; 97 double neww = 0.0; 98 //Adjust according to width, if 99 if (rect.Width * 1.0 / rect.Height > width / height) 100 { 101 newh = (height * 1.0 / width) * rect.Width; 102 neww = rect.Width; 103 //newh = (rect.Height*1.0 / rect.Width) * height; 104 //neww = width; 105 } 106 else 107 { 108 //neww = (rect.Width*1.0 / rect.Height) * width; 109 //newh = height; 110 neww = (width * 1.0 / height) * rect.Width; 111 newh = rect.Height; 112 } 113 RectangleF newRect = new RectangleF((float)(midX - neww / 2.0), (float)(midY - newh / 2.0), (float)neww, (float)newh); 114 return newRect; 115 } 116 public Bitmap RSImg2BitMap(OSGeo.GDAL.Dataset dataset, 117 Rectangle ExtentRect, int[] displayBands) 118 { 119 int x1width = ExtentRect.Width; 120 int y1height = ExtentRect.Height; 121 122 Bitmap image = new Bitmap(x1width, y1height, 123 System.Drawing.Imaging.PixelFormat.Format24bppRgb); 124 int iPixelSize = 3; 125 126 if (dataset != null) 127 { 128 BitmapData bitmapdata = image.LockBits(new 129 Rectangle(0, 0, x1width, y1height), 130 ImageLockMode.ReadWrite, image.PixelFormat); 131 int ch = 0; 132 133 try 134 { 135 unsafe 136 { 137 for (int i = 1; i <= displayBands.Length; ++i) 138 { 139 OSGeo.GDAL.Band band = dataset.GetRasterBand(displayBands[i - 1]); 140 int[] buffer = new int[x1width * y1height]; 141 band.ReadRaster(0, 0, __Geodataset.RasterXSize, 142 __Geodataset.RasterYSize, buffer, x1width, y1height, 0, 0); 143 int p_indx = 0; 144 145 if ((int)band.GetRasterColorInterpretation() == 5) 146 ch = 0; 147 if ((int)band.GetRasterColorInterpretation() == 4) 148 ch = 1; 149 if ((int)band.GetRasterColorInterpretation() == 3) 150 ch = 2; 151 if ((int)band.GetRasterColorInterpretation() != 2) 152 { 153 double maxVal = 0.0; 154 double minVal = 0.0; 155 maxVal = GetMaxWithoutNoData(dataset, 156 displayBands[i - 1], -9999.0); 157 minVal = GetMinWithoutNoData(dataset, 158 displayBands[i - 1], -9999.0); 159 for (int y = 0; y < y1height; y++) 160 { 161 byte* row = (byte*)bitmapdata.Scan0 + 162 (y * bitmapdata.Stride); 163 for (int x = 0; x < x1width; x++, p_indx++) 164 { 165 byte tempVal = shift2Byte(buffer[p_indx], maxVal, minVal, -9999.0); 166 row[x * iPixelSize + ch] = tempVal; 167 } 168 } 169 } 170 else 171 { 172 double maxVal = 0.0; 173 double minVal = 0.0; 174 maxVal = GetMaxWithoutNoData(dataset, 175 displayBands[i - 1], -9999.0); 176 minVal = GetMinWithoutNoData(dataset, 177 displayBands[i - 1], -9999.0); 178 for (int y = 0; y < y1height; y++) 179 { 180 byte* row = (byte*)bitmapdata.Scan0 + 181 (y * bitmapdata.Stride); 182 for (int x = 0; x < x1width; x++, p_indx++) 183 { 184 byte tempVal = shift2Byte<int> 185 (buffer[p_indx], maxVal, minVal, -9999.0); 186 row[x * iPixelSize] = tempVal; 187 row[x * iPixelSize + 1] = tempVal; 188 row[x * iPixelSize + 2] = tempVal; 189 } 190 } 191 } 192 ch++; 193 } 194 } 195 } 196 finally 197 { 198 image.UnlockBits(bitmapdata); 199 } 200 } 201 return image; 202 } 203 #region RASTERoperations 204 /// <summary> 205 /// Function of shift2Byte 206 /// </summary> 207 /// <remarks>this function will shift a value into a range of byte: 0~255 to be displayed in the graphics.</remarks> 208 /// <typeparam name="T">the type of the value</typeparam> 209 /// <param name="val">the value that will be converted to byte</param> 210 /// <param name="Maximum">the maximum value range</param> 211 /// <param name="Minimum">the minimum value range</param> 212 /// <returns>a value within the byte range</returns> 213 public byte shift2Byte<T>(T val, double Maximum, double Minimum) 214 { 215 double a = 255 / (Maximum - Minimum); 216 double b = 255 - (255 / (Maximum - Minimum)) * Maximum; 217 double tempVal = Convert.ToDouble(val); 218 byte value = Convert.ToByte(a * tempVal + b); 219 return value; 220 } 221 /// <summary> 222 /// Function of shift2Byte 223 /// </summary> 224 /// <remarks>this function will shift a value into a range of byte: 0~255 to be displayed in the graphics.</remarks> 225 /// <typeparam name="T">the type of the value</typeparam> 226 /// <param name="val">the value that will be converted to byte</param> 227 /// <param name="Maximum">the maximum value range</param> 228 /// <param name="Minimum">the minimum value range</param> 229 /// <param name="noData">the value for the non-sens pixel</param> 230 /// <returns>a value within the byte range</returns> 231 public byte shift2Byte<T>(T val, double Maximum, double Minimum, double noData) 232 { 233 double a = 0.0; 234 double b = 0.0; 235 double tempVal = Convert.ToDouble(val); 236 a = 254 / (Maximum - Minimum); 237 b = 255 - (254 / (Maximum - Minimum)) * Maximum; 238 if (Math.Abs(tempVal) > Math.Abs(noData)) 239 return 0; 240 try 241 { 242 return Convert.ToByte(a * tempVal + b); 243 } 244 catch 245 { 246 return 0; 247 } 248 } 249 /// <summary> 250 /// Function of GetMaxWithoutNoData 251 /// </summary> 252 /// <remarks>Get the maximum data of certain band without the nodata values.</remarks> 253 /// <param name="band">the band that will be statistically checked.</param> 254 /// <returns>the maximum values.</returns> 255 public double GetMaxWithoutNoData(OSGeo.GDAL.Dataset ds, int bandNumb, double __NoData) 256 { 257 double max = 0.0; 258 double tempMax = 0.0; 259 int index = 0; 260 Band tempBand = ds.GetRasterBand(bandNumb); 261 tempBand.GetMaximum(out tempMax, out index); 262 if (Math.Abs(tempMax) < Math.Abs(__NoData)) 263 max = tempMax; 264 else 265 { 266 OSGeo.GDAL.Band band; 267 band = ds.GetRasterBand(bandNumb); 268 //the number of columns 269 int xSize = ds.RasterXSize; 270 //the number of rows 271 int ySize = ds.RasterYSize; 272 double[] bandData = new double[xSize * ySize]; 273 //Read the data into the bandData matrix. 274 OSGeo.GDAL.CPLErr err = band.ReadRaster(0, 0, xSize, ySize, bandData, xSize, ySize, 0, 0); 275 for (long i = 0; i < xSize * ySize; i++) 276 { 277 if (bandData[i] > max & (Math.Abs(bandData[i]) < Math.Abs(__NoData))) 278 max = bandData[i]; 279 } 280 } 281 return max; 282 } 283 /// <summary> 284 /// Function of GetMinWithoutNoData 285 /// </summary> 286 /// <remarks>Get the maximum data of certain band without the nodata values.</remarks> 287 /// <param name="band">the band that will be statistically checked</param> 288 /// <returns>the maximum values.</returns> 289 public double GetMinWithoutNoData(OSGeo.GDAL.Dataset ds, int bandNumb, double __NoData) 290 { 291 double min = Math.Abs(__NoData); 292 double tempMin = 0.0; 293 int index = 0; 294 Band tempBand = ds.GetRasterBand(bandNumb); 295 tempBand.GetMinimum(out tempMin, out index); 296 if (Math.Abs(tempMin) < Math.Abs(__NoData)) 297 min = tempMin; 298 else 299 { 300 OSGeo.GDAL.Band band; 301 band = ds.GetRasterBand(bandNumb); 302 //the number of columns 303 int xSize = ds.RasterXSize; 304 //the number of rows 305 int ySize = ds.RasterYSize; 306 double[] bandData = new double[xSize * ySize]; 307 //Read the data into the bandData matrix. 308 OSGeo.GDAL.CPLErr err = band.ReadRaster(0, 0, xSize, ySize, bandData, xSize, ySize, 0, 0); 309 for (long i = 0; i < xSize * ySize; i++) 310 { 311 if (bandData[i] < min & (Math.Abs(bandData[i]) < Math.Abs(__NoData))) 312 min = bandData[i]; 313 } 314 } 315 return min; 316 } 317 /// <summary> 318 /// Funcion of GetDatasetType 319 /// </summary> 320 /// <param name="band">the band where the data type will be defined.</param> 321 /// <returns>0 is the byte, 1 is int, 2 is double, and 3 is unknown.</returns> 322 public byte GetDatasetType(OSGeo.GDAL.Band band) 323 { 324 switch (band.DataType) 325 { 326 case OSGeo.GDAL.DataType.GDT_Byte: 327 return 0; 328 case OSGeo.GDAL.DataType.GDT_CFloat32: 329 case OSGeo.GDAL.DataType.GDT_CFloat64: 330 case OSGeo.GDAL.DataType.GDT_Float32: 331 case OSGeo.GDAL.DataType.GDT_Float64: 332 return 2; 333 case OSGeo.GDAL.DataType.GDT_TypeCount: 334 case OSGeo.GDAL.DataType.GDT_Unknown: 335 return 3; 336 default: 337 return 1; 338 } 339 } 340 #endregion 341 private SceneControl sceneControl1; 342 private void Form1_Load(object sender, EventArgs e) 343 { 344 this.sceneControl1 = new AppScene.SceneControl(); 345 // 346 // sceneControl1 347 // 348 this.SuspendLayout(); 349 this.sceneControl1.Dock = System.Windows.Forms.DockStyle.Fill; 350 this.sceneControl1.Location = new System.Drawing.Point(0, 0); 351 this.sceneControl1.Name = "sceneControl1"; 352 this.sceneControl1.Size = new System.Drawing.Size(669, 457); 353 this.sceneControl1.TabIndex = 0; 354 this.panel1.Controls.Add(this.sceneControl1); 355 sceneControl1.Focus(); 356 Application.Idle += new EventHandler(sceneControl1.OnApplicationIdle); 357 this.ResumeLayout(false); 358 } 359 } 360 }