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 ...
随机推荐
- Unity资源解决方案之AssetBundle
1.什么是AssetBundle AssetBundle是Unity pro提供的一种用来存储资源的文件格式,它可以存储任意一种Unity引擎能够识别的资源,如Scene.Mesh.Material. ...
- java jdk-awt.font在centos上中文乱码的问题, 安装中文字体
有需求生成一个二维码,并且有一段文本说明,但是使用awt.font来生成中文时,一直存在乱码的问题.网上的解决办法有几种,但是在centos上亲测有用的就是如下的方法. Java代码如下:new ja ...
- Git高级操作
本文是在Git操作指南基础上衍生出来的高级操作,如果你对git不是很熟悉,建议你先阅读Git操作指南. 一.忽略提交特定文件 如果你不想让一些文件上传到git仓库中,可以让Git忽略特定文件或是目录, ...
- wm_concat函数 用法
首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来,并显示成一行,接下来上例子,看看这个神奇的函数如何应用 准备测试数据 SQL> ...
- Linux上运行Jmeter
上传jmeter到Linux服务器 unzip解压 配置环境变量vi /etc/profile: export PATH=/tmp/apache-jmeter-3.0/bin/:$PATH 刷新环境变 ...
- 通过ArcGIS Desktop数据发布ArcGIS Server
1.双击GIS Servers--->Add ArcGIS Server 2.选择Publish GIS Services 3.输入Server URL:http://localhost:608 ...
- PHP-005
MySql 表列默认时间类型设置:数据类型:timestamp,缺省值:CURRENT_TIMESTAMP
- Spring装配Bean的过程
首先说一个概念:“懒加载” 懒加载:就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中. spring配置文件中be ...
- Python 使用正则表达式匹配URL网址
使用正则表达式匹配以 .com 或 .cn 为域名后缀的URL地址 In [1]: import re In [2]: str = "http://www.baidu.com/" ...
- mysql增删改查基本语句
mysql的增删改查属于基本操作,又被简称CRUD,其中删用的较少,毕竟这个功能给用户是是非常危险的,就是客户删除的数据也没有真正的删除,其中查询是十分常用的. 1 mysql数据库增加:create ...