C#+GDAL读取影像(1)
环境:VS2010,C#,GDAL1.7
读取影像:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Diagnostics;
- using System.Drawing.Imaging;
- using OSGeo.GDAL;
- using AppScene;
- namespace GdalReader
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- string __ImagePath = string.Empty;
- private OSGeo.GDAL.Dataset __Geodataset;
- private int[] __DisplayBands;
- private Rectangle __DrawRect;
- private Bitmap __BitMap;
- private void btnBrower_Click(object sender, EventArgs e)
- {
- OpenFileDialog dlg = new OpenFileDialog();
- dlg.Title = "";
- dlg.Filter = "Img(*.img)|*.img";
- if (dlg.ShowDialog() == DialogResult.OK)
- {
- OSGeo.GDAL.Gdal.AllRegister();
- __ImagePath = dlg.FileName;
- txtPath.Text = __ImagePath;
- OSGeo.GDAL.Dataset dataset = OSGeo.GDAL.Gdal.Open(__ImagePath, OSGeo.GDAL.Access.GA_ReadOnly);
- __Geodataset = dataset;
- if (__Geodataset != null)
- {
- if (__Geodataset.RasterCount >= )
- __DisplayBands = new int[] { , , };
- else
- __DisplayBands = new int[] { , , };
- }
- double[] dd = new double[];
- dataset.GetGeoTransform(dd);
- string prj = dataset.GetProjection();
- string str = string.Format("波段数目:{0}\n行数:{1};列数:{2}\n坐标参考:{3},{4},{5},{6}\n", __Geodataset.RasterCount, __Geodataset.RasterXSize, __Geodataset.RasterYSize, dd[], dd[], dd[], dd[]);
- str += prj + "\n";
- for (int i = ; i <= __Geodataset.RasterCount; ++i)
- {
- OSGeo.GDAL.Band band = dataset.GetRasterBand(i);
- str += "波段" + i + ":" + band.DataType.ToString();
- }
- richTextBox1.Text = str;
- InitialIMG();
- SimpleRasterShow simRaster = new SimpleRasterShow("");
- simRaster.IsOn = true;
- simRaster.bitmap = __BitMap;
- sceneControl1.CurrentWorld.RenderableObjects.ChildObjects.Add(simRaster);
- }
- }
- public void InitialIMG()
- {
- if (__Geodataset != null)
- {
- Rectangle rect = new Rectangle(, , __Geodataset.RasterXSize, __Geodataset.RasterYSize);
- float width = (float)this.Width;
- float height = (float)this.Height;
- RectangleF Extent = ExtRect(rect, width, height);
- double scale = Extent.Width / this.Width;
- //double scaley = Extent.Height / this.Height;
- double bufWidth = __Geodataset.RasterXSize / scale;
- double bufHeight = __Geodataset.RasterYSize / scale;
- Debug.WriteLine("Buffered width is:" + bufWidth);
- Debug.WriteLine("Buffered height is:" + bufHeight);
- double bufX = (this.Width - bufWidth) / 2.0;
- double bufY = (this.Height - bufHeight) / 2.0;
- __DrawRect = new Rectangle((int)bufX, (int)bufY, (int)bufWidth, (int)bufHeight);
- Rectangle ExtentRect = new Rectangle(, , (int)bufWidth, (int)bufHeight);
- //__DispRectCenter = new PointF((float)(bufX + bufWidth / 2.0), (float)(bufY + bufHeight / 2.0));
- // __Zoom = (float)scale;
- //__Zoom=(float)(scalex>scaley?scalex:scaley);
- __BitMap = RSImg2BitMap(__Geodataset, ExtentRect, __DisplayBands);
- // Invalidate();
- }
- }
- public RectangleF ExtRect(Rectangle rect, float width, float height)
- {
- double midX = rect.X + rect.Width / 2.0;
- double midY = rect.Y + rect.Height / 2.0;
- double newh = 0.0;
- double neww = 0.0;
- //Adjust according to width, if
- if (rect.Width * 1.0 / rect.Height > width / height)
- {
- newh = (height * 1.0 / width) * rect.Width;
- neww = rect.Width;
- //newh = (rect.Height*1.0 / rect.Width) * height;
- //neww = width;
- }
- else
- {
- //neww = (rect.Width*1.0 / rect.Height) * width;
- //newh = height;
- neww = (width * 1.0 / height) * rect.Width;
- newh = rect.Height;
- }
- RectangleF newRect = new RectangleF((float)(midX - neww / 2.0), (float)(midY - newh / 2.0), (float)neww, (float)newh);
- return newRect;
- }
- public Bitmap RSImg2BitMap(OSGeo.GDAL.Dataset dataset,
- Rectangle ExtentRect, int[] displayBands)
- {
- int x1width = ExtentRect.Width;
- int y1height = ExtentRect.Height;
- Bitmap image = new Bitmap(x1width, y1height,
- System.Drawing.Imaging.PixelFormat.Format24bppRgb);
- int iPixelSize = ;
- if (dataset != null)
- {
- BitmapData bitmapdata = image.LockBits(new
- Rectangle(, , x1width, y1height),
- ImageLockMode.ReadWrite, image.PixelFormat);
- int ch = ;
- try
- {
- unsafe
- {
- for (int i = ; i <= displayBands.Length; ++i)
- {
- OSGeo.GDAL.Band band = dataset.GetRasterBand(displayBands[i - ]);
- int[] buffer = new int[x1width * y1height];
- band.ReadRaster(, , __Geodataset.RasterXSize,
- __Geodataset.RasterYSize, buffer, x1width, y1height, , );
- int p_indx = ;
- if ((int)band.GetRasterColorInterpretation() == )
- ch = ;
- if ((int)band.GetRasterColorInterpretation() == )
- ch = ;
- if ((int)band.GetRasterColorInterpretation() == )
- ch = ;
- if ((int)band.GetRasterColorInterpretation() != )
- {
- double maxVal = 0.0;
- double minVal = 0.0;
- maxVal = GetMaxWithoutNoData(dataset,
- displayBands[i - ], -9999.0);
- minVal = GetMinWithoutNoData(dataset,
- displayBands[i - ], -9999.0);
- for (int y = ; y < y1height; y++)
- {
- byte* row = (byte*)bitmapdata.Scan0 +
- (y * bitmapdata.Stride);
- for (int x = ; x < x1width; x++, p_indx++)
- {
- byte tempVal = shift2Byte(buffer[p_indx], maxVal, minVal, -9999.0);
- row[x * iPixelSize + ch] = tempVal;
- }
- }
- }
- else
- {
- double maxVal = 0.0;
- double minVal = 0.0;
- maxVal = GetMaxWithoutNoData(dataset,
- displayBands[i - ], -9999.0);
- minVal = GetMinWithoutNoData(dataset,
- displayBands[i - ], -9999.0);
- for (int y = ; y < y1height; y++)
- {
- byte* row = (byte*)bitmapdata.Scan0 +
- (y * bitmapdata.Stride);
- for (int x = ; x < x1width; x++, p_indx++)
- {
- byte tempVal = shift2Byte<int>
- (buffer[p_indx], maxVal, minVal, -9999.0);
- row[x * iPixelSize] = tempVal;
- row[x * iPixelSize + ] = tempVal;
- row[x * iPixelSize + ] = tempVal;
- }
- }
- }
- ch++;
- }
- }
- }
- finally
- {
- image.UnlockBits(bitmapdata);
- }
- }
- return image;
- }
- #region RASTERoperations
- /// <summary>
- /// Function of shift2Byte
- /// </summary>
- /// <remarks>this function will shift a value into a range of byte: 0~255 to be displayed in the graphics.</remarks>
- /// <typeparam name="T">the type of the value</typeparam>
- /// <param name="val">the value that will be converted to byte</param>
- /// <param name="Maximum">the maximum value range</param>
- /// <param name="Minimum">the minimum value range</param>
- /// <returns>a value within the byte range</returns>
- public byte shift2Byte<T>(T val, double Maximum, double Minimum)
- {
- double a = / (Maximum - Minimum);
- double b = - ( / (Maximum - Minimum)) * Maximum;
- double tempVal = Convert.ToDouble(val);
- byte value = Convert.ToByte(a * tempVal + b);
- return value;
- }
- /// <summary>
- /// Function of shift2Byte
- /// </summary>
- /// <remarks>this function will shift a value into a range of byte: 0~255 to be displayed in the graphics.</remarks>
- /// <typeparam name="T">the type of the value</typeparam>
- /// <param name="val">the value that will be converted to byte</param>
- /// <param name="Maximum">the maximum value range</param>
- /// <param name="Minimum">the minimum value range</param>
- /// <param name="noData">the value for the non-sens pixel</param>
- /// <returns>a value within the byte range</returns>
- public byte shift2Byte<T>(T val, double Maximum, double Minimum, double noData)
- {
- double a = 0.0;
- double b = 0.0;
- double tempVal = Convert.ToDouble(val);
- a = / (Maximum - Minimum);
- b = - ( / (Maximum - Minimum)) * Maximum;
- if (Math.Abs(tempVal) > Math.Abs(noData))
- return ;
- try
- {
- return Convert.ToByte(a * tempVal + b);
- }
- catch
- {
- return ;
- }
- }
- /// <summary>
- /// Function of GetMaxWithoutNoData
- /// </summary>
- /// <remarks>Get the maximum data of certain band without the nodata values.</remarks>
- /// <param name="band">the band that will be statistically checked.</param>
- /// <returns>the maximum values.</returns>
- public double GetMaxWithoutNoData(OSGeo.GDAL.Dataset ds, int bandNumb, double __NoData)
- {
- double max = 0.0;
- double tempMax = 0.0;
- int index = ;
- Band tempBand = ds.GetRasterBand(bandNumb);
- tempBand.GetMaximum(out tempMax, out index);
- if (Math.Abs(tempMax) < Math.Abs(__NoData))
- max = tempMax;
- else
- {
- OSGeo.GDAL.Band band;
- band = ds.GetRasterBand(bandNumb);
- //the number of columns
- int xSize = ds.RasterXSize;
- //the number of rows
- int ySize = ds.RasterYSize;
- double[] bandData = new double[xSize * ySize];
- //Read the data into the bandData matrix.
- OSGeo.GDAL.CPLErr err = band.ReadRaster(, , xSize, ySize, bandData, xSize, ySize, , );
- for (long i = ; i < xSize * ySize; i++)
- {
- if (bandData[i] > max & (Math.Abs(bandData[i]) < Math.Abs(__NoData)))
- max = bandData[i];
- }
- }
- return max;
- }
- /// <summary>
- /// Function of GetMinWithoutNoData
- /// </summary>
- /// <remarks>Get the maximum data of certain band without the nodata values.</remarks>
- /// <param name="band">the band that will be statistically checked</param>
- /// <returns>the maximum values.</returns>
- public double GetMinWithoutNoData(OSGeo.GDAL.Dataset ds, int bandNumb, double __NoData)
- {
- double min = Math.Abs(__NoData);
- double tempMin = 0.0;
- int index = ;
- Band tempBand = ds.GetRasterBand(bandNumb);
- tempBand.GetMinimum(out tempMin, out index);
- if (Math.Abs(tempMin) < Math.Abs(__NoData))
- min = tempMin;
- else
- {
- OSGeo.GDAL.Band band;
- band = ds.GetRasterBand(bandNumb);
- //the number of columns
- int xSize = ds.RasterXSize;
- //the number of rows
- int ySize = ds.RasterYSize;
- double[] bandData = new double[xSize * ySize];
- //Read the data into the bandData matrix.
- OSGeo.GDAL.CPLErr err = band.ReadRaster(, , xSize, ySize, bandData, xSize, ySize, , );
- for (long i = ; i < xSize * ySize; i++)
- {
- if (bandData[i] < min & (Math.Abs(bandData[i]) < Math.Abs(__NoData)))
- min = bandData[i];
- }
- }
- return min;
- }
- /// <summary>
- /// Funcion of GetDatasetType
- /// </summary>
- /// <param name="band">the band where the data type will be defined.</param>
- /// <returns>0 is the byte, 1 is int, 2 is double, and 3 is unknown.</returns>
- public byte GetDatasetType(OSGeo.GDAL.Band band)
- {
- switch (band.DataType)
- {
- case OSGeo.GDAL.DataType.GDT_Byte:
- return ;
- case OSGeo.GDAL.DataType.GDT_CFloat32:
- case OSGeo.GDAL.DataType.GDT_CFloat64:
- case OSGeo.GDAL.DataType.GDT_Float32:
- case OSGeo.GDAL.DataType.GDT_Float64:
- return ;
- case OSGeo.GDAL.DataType.GDT_TypeCount:
- case OSGeo.GDAL.DataType.GDT_Unknown:
- return ;
- default:
- return ;
- }
- }
- #endregion
- private SceneControl sceneControl1;
- private void Form1_Load(object sender, EventArgs e)
- {
- this.sceneControl1 = new AppScene.SceneControl();
- //
- // sceneControl1
- //
- this.SuspendLayout();
- this.sceneControl1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.sceneControl1.Location = new System.Drawing.Point(, );
- this.sceneControl1.Name = "sceneControl1";
- this.sceneControl1.Size = new System.Drawing.Size(, );
- this.sceneControl1.TabIndex = ;
- this.panel1.Controls.Add(this.sceneControl1);
- sceneControl1.Focus();
- Application.Idle += new EventHandler(sceneControl1.OnApplicationIdle);
- this.ResumeLayout(false);
- }
- }
- }
在AppScene中渲染对象:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using AppScene;
- using Microsoft.DirectX.Direct3D;
- using Microsoft.DirectX;
- using System.Drawing;
- using System.IO;
- using System.Runtime.Serialization.Formatters.Binary;
- using Utility;
- namespace GdalReader
- {
- class SimpleRasterShow : WorldWind.Renderable.RenderableObject
- {
- private CustomVertex.PositionTextured[] vertices;// 定义顶点变量
- private Texture texture;//定义贴图变量
- private Material material;//定义材质变量
- public Bitmap bitmap = null;
- public SimpleRasterShow(string name)
- : base(name)
- {
- }
- public override void Initialize(DrawArgs drawArgs)
- {
- this.isInitialized = true;
- LoadTexturesAndMaterials(drawArgs);
- VertexDeclaration();
- }
- public override void Update(DrawArgs drawArgs)
- {
- if (!isInitialized && isOn)
- {
- Initialize(drawArgs);
- }
- }
- public override void Render(DrawArgs drawArgs)
- {
- if (!isInitialized || !isOn)
- return;
- VertexFormats format = drawArgs.Device.VertexFormat;
- FillMode currentCull = drawArgs.Device.RenderState.FillMode;
- int currentColorOp = drawArgs.Device.GetTextureStageStateInt32(, TextureStageStates.ColorOperation);
- int zBuffer = drawArgs.Device.GetRenderStateInt32(RenderStates.ZEnable);
- try
- {
- drawArgs.Device.RenderState.FillMode = FillMode.Solid;
- drawArgs.Device.RenderState.Lighting = false;
- drawArgs.Device.RenderState.DiffuseMaterialSource = ColorSource.Color1;
- drawArgs.Device.RenderState.AlphaBlendEnable = true;
- drawArgs.Device.RenderState.AlphaTestEnable = true;
- drawArgs.Device.RenderState.ReferenceAlpha = ;
- drawArgs.Device.RenderState.AlphaFunction = Compare.Greater;
- drawArgs.Device.RenderState.SourceBlend = Blend.SourceAlpha;
- drawArgs.Device.RenderState.DestinationBlend = Blend.BothInvSourceAlpha;
- drawArgs.Device.RenderState.BlendOperation = BlendOperation.Add;
- drawArgs.Device.SetTexture(, texture);//设置贴图
- drawArgs.Device.TextureState[].ColorOperation = TextureOperation.Modulate;
- drawArgs.Device.TextureState[].ColorArgument1 = TextureArgument.TextureColor;
- drawArgs.Device.TextureState[].ColorArgument2 = TextureArgument.Current;
- drawArgs.Device.TextureState[].AlphaOperation = TextureOperation.SelectArg2;
- drawArgs.Device.TextureState[].AlphaArgument1 = TextureArgument.TextureColor;
- //device.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse;
- drawArgs.Device.VertexFormat = CustomVertex.PositionTextured.Format;
- drawArgs.Device.DrawUserPrimitives(PrimitiveType.TriangleList, , vertices);
- }
- catch (Exception ex)
- {
- Log.Write(ex);
- }
- finally
- {
- drawArgs.Device.VertexFormat = format;
- drawArgs.Device.RenderState.FillMode = currentCull;
- drawArgs.Device.SetTextureStageState(, TextureStageStates.ColorOperation, currentColorOp);
- drawArgs.Device.SetRenderState(RenderStates.ZEnable, zBuffer);
- drawArgs.Device.Indices = null;
- }
- }
- private void VertexDeclaration1()//定义顶点1
- {
- vertices = new CustomVertex.PositionTextured[];
- vertices[].Position = new Vector3(10f, 10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- vertices[].Position = new Vector3(-10f, -10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- vertices[].Position = new Vector3(10f, -10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- }
- private void VertexDeclaration()//定义顶点
- {
- vertices = new CustomVertex.PositionTextured[];
- vertices[].Position = new Vector3(10f, 10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- vertices[].Position = new Vector3(-10f, -10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- vertices[].Position = new Vector3(10f, -10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- vertices[].Position = new Vector3(-10f, -10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- vertices[].Position = new Vector3(10f, 10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- vertices[].Position = new Vector3(-10f, 10f, 0f);
- vertices[].Tu = ;
- vertices[].Tv = ;
- }
- private void LoadTexturesAndMaterials(DrawArgs args)//导入贴图和材质
- {
- material = new Material();
- material.Diffuse = Color.White;
- material.Specular = Color.LightGray;
- material.SpecularSharpness = 15.0F;
- args.Device.Material = material;
- //MemoryStream memory = new MemoryStream();
- //BinaryFormatter formatter = new BinaryFormatter();
- //formatter.Serialize(memory, bitmap);
- int bufferSize = bitmap.Height * bitmap.Width * ;
- System.IO.MemoryStream memory = new System.IO.MemoryStream();
- bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
- memory.Seek(, SeekOrigin.Begin);
- texture = TextureLoader.FromStream(args.Device, memory);
- //if (File.Exists(@"d:\temp.jpg"))
- //{
- // File.Delete(@"d:\temp.jpg");
- //}
- //bitmap.Save(@"d:\temp.jpg");
- //texture = TextureLoader.FromFile(args.Device, @"d:\temp.jpg");
- }
- public override void Dispose()
- {
- }
- public override bool PerformSelectionAction(DrawArgs drawArgs)
- {
- return true;
- // throw new NotImplementedException();
- }
- }
- }
结果:
存在的问题:
其实就是读取影像的时候构建了一个BitMap,没有和金字塔结合,没有实现在放大缩小的时候动态加载金字塔数据。对于特别大的影像加载会失败!
其实初始加载的时候应该根据画布的大小,加载一个缩略的全局影像,放大过程中动态加载不同级别的金字塔影像!
C#+GDAL读取影像(1)的更多相关文章
- GDAL读取影像并插值
影像读取 并缩放 读取大影像某一部分,并缩放到指定大小,我们有时会用如下代码: #include "gdal.h" #include "gdal_priv.h" ...
- GDAL读取的坐标起点在像素左上角还是像素中心?
目录 1. 问题 2. 结论 3. 例外 1. 问题 笔者在处理地理栅格数据的时候,总是会发生偏差半个像素的问题. 比如说通过ArcMap打开一张.tif,查看其地理信息:同时用记事本打开.tfw,比 ...
- 使用C#版本GDAL读取复数图像
GDAL的C#版本虽然在很多算法接口没有导出,但是在读写数据中的接口基本上都是完全导出了.使用ReadRaster和WriteRaster方法来进行读写,同时对这两个方法进行了重载,对于常用的数据类型 ...
- GDAL读取Shp问题解决:Unable to open EPSG support file gcs.csv
在GIS软件的开发中,经常用到开源库GDAL读取Shp数据,当shp数据中包含投影信息时,可能会遇到“Unable to open EPSG support file gcs.csv”错误提示,该错误 ...
- C#使用GDAL读取与创建影像
C#下GDAL的使用这里就不多赘述了.參见上一篇博客. 代码中都加了凝视,这里就不再一一叙述了.代码例如以下: class FloodSimulation { #region 类成员变量 public ...
- [GDAL]读取HDF格式的calipso数据
探测地球云层分布的CloudSat和CALIPSO卫星 http://www.nasa.gov/mission_pages/calipso/main/index.html http://www.nas ...
- GDAL读取tiff文件/C++源码
// gdal_geotiff.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "gdal_priv.h&quo ...
- AE + GDAL实现影像按标准图幅分割(上)
最近有个项目,其中有个功能是要将遥感影像按标准图幅分割,一开始用AE的接口,慢的让人抓狂,就改用GDAL,速度提升很大.我主要通过http://blog.csdn.net/liminlu0314/学习 ...
- 【GIS】GDAL Python 影像裁剪
# -*- coding: utf-8 -*- """ Created on Fri Nov 30 11:45:03 2018 @author: Administrato ...
随机推荐
- 浅谈session测试
Session 是用于保持状态的基于 Web 服务器的方法,在 Web 服务器上保持用户的状态信息供在任何时间从任何页访问.Session 允许通过将对象存储在 Web 服务器的内存中在整个用户会话过 ...
- PHP开启伪静态配置
1.检测Apache是否开启mod_rewrite功能 可以通过php提供的phpinfo()函数查看环境配置,找到“Loaded Modules”,其中列出了所有apache2handler已经开启 ...
- Java输入输出流(2)
6. Java.IO流类库 1. io流的四个基本类 java.io包中包括了流式I/O所须要的全部类. 在java.io包中有四个基本类:InputStream.OutputStream及Reade ...
- vuex的简单使用
使用vuex进行组件间数据的管理 npm i vuex -S main.js import Vue from 'vue' import App from './App.vue' import stor ...
- RF使用的相关库API
RF内置库: http://robotframework.org/robotframework/ SSHLibrary: ---WEB自动化测试 http://robotframework.org ...
- /etc/redhat-release
该文件用于记录 RedHat 的发行版本信息 [root@localhost ~]$ cat /etc/redhat-release CentOS release 6.5 (Final)
- DiscuzX的目录权限设置1
经常有朋友遇到Discuz目录权限设置出错的问题,网上千奇百怪的教程非常多,所谓的终极安全的教程更是满天飞,各种所谓的安全加强软件也随处可见,可实际过程中发现,老手用不上,新手则只会因为这些东西徒增麻 ...
- git Xcode
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://2009315319.blog.51cto.com/701759/1158515 ...
- mount: block device /dev/cdrom is write-protected, mounting read-only 解决方法
[root@localhost ~]# mount /dev/cdrom /mnt/cdrom/ mount: block device /dev/sr0 is write-protected, mo ...
- eclipse export runnable jar
如果要导出可运行的JAR文件,需要选择Runnable Jar File. 方法/步骤 1. 选择要到处JAR文件的工程,右键选择“Export”: 2. 选择“Java-->Run ...