博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#+GDAL读取影像(1)
阅读量:6336 次
发布时间:2019-06-22

本文共 24093 字,大约阅读时间需要 80 分钟。

环境: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             else107             {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(new129                                         Rectangle(0, 0, x1width, y1height),130                                         ImageLockMode.ReadWrite, image.PixelFormat);131                 int ch = 0;132 133                 try134                 {135                     unsafe136                     {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                             else171                             {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
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 finally197 {198 image.UnlockBits(bitmapdata);199 }200 }201 return image;202 }203 #region RASTERoperations204 ///
205 /// Function of shift2Byte206 /// 207 ///
this function will shift a value into a range of byte: 0~255 to be displayed in the graphics.
208 ///
the type of the value
209 ///
the value that will be converted to byte210 ///
the maximum value range211 ///
the minimum value range212 ///
a value within the byte range
213 public byte shift2Byte
(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 ///
222 /// Function of shift2Byte223 /// 224 ///
this function will shift a value into a range of byte: 0~255 to be displayed in the graphics.
225 ///
the type of the value
226 ///
the value that will be converted to byte227 ///
the maximum value range228 ///
the minimum value range229 ///
the value for the non-sens pixel230 ///
a value within the byte range
231 public byte shift2Byte
(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 try241 {242 return Convert.ToByte(a * tempVal + b);243 }244 catch245 {246 return 0;247 }248 }249 ///
250 /// Function of GetMaxWithoutNoData251 /// 252 ///
Get the maximum data of certain band without the nodata values.
253 ///
the band that will be statistically checked.254 ///
the maximum values.
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 else265 {266 OSGeo.GDAL.Band band;267 band = ds.GetRasterBand(bandNumb);268 //the number of columns269 int xSize = ds.RasterXSize;270 //the number of rows271 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 ///
284 /// Function of GetMinWithoutNoData285 /// 286 ///
Get the maximum data of certain band without the nodata values.
287 ///
the band that will be statistically checked288 ///
the maximum values.
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 else299 {300 OSGeo.GDAL.Band band;301 band = ds.GetRasterBand(bandNumb);302 //the number of columns303 int xSize = ds.RasterXSize;304 //the number of rows305 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 ///
318 /// Funcion of GetDatasetType319 /// 320 ///
the band where the data type will be defined.321 ///
0 is the byte, 1 is int, 2 is double, and 3 is unknown.
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 #endregion341 private SceneControl sceneControl1;342 private void Form1_Load(object sender, EventArgs e)343 {344 this.sceneControl1 = new AppScene.SceneControl();345 // 346 // sceneControl1347 // 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,没有和金字塔结合,没有实现在放大缩小的时候动态加载金字塔数据。对于特别大的影像加载会失败!

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

转载于:https://www.cnblogs.com/yhlx125/p/3371051.html

你可能感兴趣的文章
Codeforces Round #256 (Div. 2) D. Multiplication Table 【二分】
查看>>
ARM汇编指令格式
查看>>
HDU-2044-一只小蜜蜂
查看>>
HDU-1394-Minimum Inversion Number
查看>>
df -h 卡住
查看>>
[转] createObjectURL方法 实现本地图片预览
查看>>
JavaScript—DOM编程核心.
查看>>
JavaScript碎片
查看>>
Bootstrap-下拉菜单
查看>>
soapUi 接口测试
查看>>
【c学习-12】
查看>>
工作中MySql的了解到的小技巧
查看>>
loadrunner-2-12日志解析
查看>>
C# Memcached缓存
查看>>
iOS开发NSLayoutConstraint代码自动布局
查看>>
正则表达式
查看>>
mysql [ERROR] Can't create IP socket: Permission denied
查看>>
PBRT笔记(4)——颜色和辐射度
查看>>
CustomView的手势缩放总结
查看>>
linux复制指定目录下的全部文件到另一个目录中,linux cp 文件夹
查看>>