zoukankan      html  css  js  c++  java
  • 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}
    行数:{1};列数:{2}
    坐标参考:{3},{4},{5},{6}
    ", __Geodataset.RasterCount, __Geodataset.RasterXSize, __Geodataset.RasterYSize, dd[0], dd[1], dd[2], dd[3]);
     51                 str += prj + "
    ";
     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:	emp.jpg"))
    146             //{
    147             //    File.Delete(@"d:	emp.jpg");
    148             //}
    149             //bitmap.Save(@"d:	emp.jpg");
    150             //texture = TextureLoader.FromFile(args.Device, @"d:	emp.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,没有和金字塔结合,没有实现在放大缩小的时候动态加载金字塔数据。对于特别大的影像加载会失败!

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

  • 相关阅读:
    spring boot 2.1学习笔记【五】SpringBootTest单元测试及日志
    Java网络编程-UDP
    Java网络编程-TCP
    String的特性
    内存池的使用
    软件定时器的使用
    邮箱
    事件集
    线程优先级翻转
    临界区,互斥量与信号量
  • 原文地址:https://www.cnblogs.com/yhlx125/p/3371051.html
Copyright © 2011-2022 走看看