C#+GDAL读取影像(1)

环境: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 }
View Code

在AppScene中渲染对象:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using AppScene;
  6 using Microsoft.DirectX.Direct3D;
  7 using Microsoft.DirectX;
  8 using System.Drawing;
  9 using System.IO;
 10 using System.Runtime.Serialization.Formatters.Binary;
 11 using Utility;
 12 
 13 namespace GdalReader
 14 {
 15     class SimpleRasterShow : WorldWind.Renderable.RenderableObject
 16     {
 17         private CustomVertex.PositionTextured[] vertices;// 定义顶点变量
 18         private Texture texture;//定义贴图变量 
 19         private Material material;//定义材质变量 
 20         public Bitmap bitmap = null;
 21         public SimpleRasterShow(string name)
 22             : base(name)
 23         {
 24 
 25         }
 26         public override void Initialize(DrawArgs drawArgs)
 27         {
 28             this.isInitialized = true;
 29             LoadTexturesAndMaterials(drawArgs);
 30             VertexDeclaration();
 31         }
 32 
 33         public override void Update(DrawArgs drawArgs)
 34         {
 35             if (!isInitialized && isOn)
 36             {
 37                 Initialize(drawArgs);
 38             }
 39         }
 40 
 41         public override void Render(DrawArgs drawArgs)
 42         {
 43             if (!isInitialized || !isOn)
 44                 return;
 45 
 46             VertexFormats format = drawArgs.Device.VertexFormat;
 47             FillMode currentCull = drawArgs.Device.RenderState.FillMode;
 48             int currentColorOp = drawArgs.Device.GetTextureStageStateInt32(0, TextureStageStates.ColorOperation);
 49             int zBuffer = drawArgs.Device.GetRenderStateInt32(RenderStates.ZEnable);
 50             try
 51             {
 52                 drawArgs.Device.RenderState.FillMode = FillMode.Solid;
 53                 drawArgs.Device.RenderState.Lighting = false;
 54 
 55                 drawArgs.Device.RenderState.DiffuseMaterialSource = ColorSource.Color1;
 56                 drawArgs.Device.RenderState.AlphaBlendEnable = true;
 57                 drawArgs.Device.RenderState.AlphaTestEnable = true;
 58 
 59                 drawArgs.Device.RenderState.ReferenceAlpha = 20;
 60                 drawArgs.Device.RenderState.AlphaFunction = Compare.Greater;
 61 
 62                 drawArgs.Device.RenderState.SourceBlend = Blend.SourceAlpha;
 63                 drawArgs.Device.RenderState.DestinationBlend = Blend.BothInvSourceAlpha;
 64                 drawArgs.Device.RenderState.BlendOperation = BlendOperation.Add;
 65 
 66                 drawArgs.Device.SetTexture(0, texture);//设置贴图 
 67                 drawArgs.Device.TextureState[0].ColorOperation = TextureOperation.Modulate;
 68                 drawArgs.Device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
 69                 drawArgs.Device.TextureState[0].ColorArgument2 = TextureArgument.Current;
 70                 drawArgs.Device.TextureState[0].AlphaOperation = TextureOperation.SelectArg2;
 71                 drawArgs.Device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
 72                 //device.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse;
 73 
 74                 drawArgs.Device.VertexFormat = CustomVertex.PositionTextured.Format;
 75                 drawArgs.Device.DrawUserPrimitives(PrimitiveType.TriangleList, 2, vertices);
 76             }
 77             catch (Exception ex)
 78             {
 79                 Log.Write(ex);
 80             }
 81             finally
 82             {
 83                 drawArgs.Device.VertexFormat = format;
 84                 drawArgs.Device.RenderState.FillMode = currentCull;
 85                 drawArgs.Device.SetTextureStageState(0, TextureStageStates.ColorOperation, currentColorOp);
 86                 drawArgs.Device.SetRenderState(RenderStates.ZEnable, zBuffer);
 87                 drawArgs.Device.Indices = null;
 88             }
 89         }
 90 
 91         private void VertexDeclaration1()//定义顶点1 
 92         {
 93             vertices = new CustomVertex.PositionTextured[3];
 94             vertices[0].Position = new Vector3(10f, 10f, 0f);
 95             vertices[0].Tu = 1;
 96             vertices[0].Tv = 0;
 97             vertices[1].Position = new Vector3(-10f, -10f, 0f);
 98             vertices[1].Tu = 0;
 99             vertices[1].Tv = 1;
100             vertices[2].Position = new Vector3(10f, -10f, 0f);
101             vertices[2].Tu = 1;
102             vertices[2].Tv = 1;
103         }
104         private void VertexDeclaration()//定义顶点 
105         {
106             vertices = new CustomVertex.PositionTextured[6];
107             vertices[0].Position = new Vector3(10f, 10f, 0f);
108             vertices[0].Tu = 1;
109             vertices[0].Tv = 0;
110             vertices[1].Position = new Vector3(-10f, -10f, 0f);
111             vertices[1].Tu = 0;
112             vertices[1].Tv = 1;
113             vertices[2].Position = new Vector3(10f, -10f, 0f);
114             vertices[2].Tu = 1;
115             vertices[2].Tv = 1;
116             vertices[3].Position = new Vector3(-10f, -10f, 0f);
117             vertices[3].Tu = 0;
118             vertices[3].Tv = 1;
119             vertices[4].Position = new Vector3(10f, 10f, 0f);
120             vertices[4].Tu = 1;
121             vertices[4].Tv = 0;
122             vertices[5].Position = new Vector3(-10f, 10f, 0f);
123             vertices[5].Tu = 0;
124             vertices[5].Tv = 0;
125 
126         }
127 
128         private void LoadTexturesAndMaterials(DrawArgs args)//导入贴图和材质 
129         {
130             material = new Material();
131             material.Diffuse = Color.White;
132             material.Specular = Color.LightGray;
133             material.SpecularSharpness = 15.0F;
134             args.Device.Material = material;
135             //MemoryStream memory = new MemoryStream();
136             //BinaryFormatter formatter = new BinaryFormatter();
137             //formatter.Serialize(memory, bitmap);
138             int bufferSize = bitmap.Height * bitmap.Width * 4;
139 
140             System.IO.MemoryStream memory = new System.IO.MemoryStream();
141             
142             bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
143             memory.Seek(0, SeekOrigin.Begin);
144             texture = TextureLoader.FromStream(args.Device, memory);
145             //if (File.Exists(@"d:\temp.jpg"))
146             //{
147             //    File.Delete(@"d:\temp.jpg");
148             //}
149             //bitmap.Save(@"d:\temp.jpg");
150             //texture = TextureLoader.FromFile(args.Device, @"d:\temp.jpg");
151         }
152 
153         public override void Dispose()
154         {
155         }
156 
157         public override bool PerformSelectionAction(DrawArgs drawArgs)
158         {
159             return true;
160             // throw new NotImplementedException();
161         }
162     }
163 }
View Code

结果:

存在的问题:

其实就是读取影像的时候构建了一个BitMap,没有和金字塔结合,没有实现在放大缩小的时候动态加载金字塔数据。对于特别大的影像加载会失败!

其实初始加载的时候应该根据画布的大小,加载一个缩略的全局影像,放大过程中动态加载不同级别的金字塔影像!

posted @ 2013-10-15 21:27  太一吾鱼水  阅读(3169)  评论(0编辑  收藏  举报