一 引言
在C# & GDAL 学习一中我写了如何用GDAL读取栅格图像的基本信息。
本篇内容是接着学习一,如何保存一个栅格图像。
在这里不加啰嗦了,主要代码我会把注释写的很清楚。
二 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OSGeo.GDAL;
using System.Drawing;
using System.Drawing.Imaging;
namespace GDALRead
{
class Program
{
public static void usage()
{
Console.WriteLine("usage");
System.Environment.Exit(-1);
}
public static void Main(string[] args)
{
if (args.Length < 2) usage();
Console.WriteLine("args包括两个字符串,一个是filename及路径,一个是outfilename及路径");
try
{
Gdal.AllRegister();
Dataset ds = Gdal.Open(args[0],Access.GA_ReadOnly);//读取filename栅格图像
if (ds==null)
{
Console.WriteLine("Can't open " + args[0]);
System.Environment.Exit(-1);
}
Console.WriteLine("raster dataset parameters:");
Console.WriteLine(" Projection:" + ds.GetProjectionRef());
Console.WriteLine(" Rastercount:" + ds.RasterCount);//RasterCount是波段数
Console.WriteLine(" RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")");
/************************************************************************/
/* Get Driver */
/************************************************************************/
Driver drv = ds.GetDriver();
if (drv ==null)
{
Console.WriteLine("Can't get driver");
System.Environment.Exit(-1);
}
Console.WriteLine("using driver" + drv.LongName);
/************************************************************************/
/* Get raster band */
/************************************************************************/
for (int iBand=1;iBand<=ds.RasterCount;iBand++)
{
Band band = ds.GetRasterBand(iBand);
Console.WriteLine("Band" + iBand + ":");
Console.WriteLine(" DataType:" + band.DataType);
Console.WriteLine(" Size (" + band.XSize + "," + band.YSize + ")");
Console.WriteLine(" PaletteInterp: " + band.GetRasterColorInterpretation().ToString()); //调色板图像
}
/************************************************************************/
/* Processing the raster
/************************************************************************/
SaveBitmapBuffered(ds, args[1]);
}
catch (System.Exception ex)
{
Console.WriteLine("Application error: " + ex.Message);
}
Console.ReadLine();
}
private static void SaveBitmapBuffered(Dataset ds, string filename)
{
Band redBand = ds.GetRasterBand(1);
if (redBand.GetRasterColorInterpretation() != ColorInterp.GCI_RedBand)
{
Console.WriteLine("Non RGB images are not supported by this sample! ColorInterp = " +
redBand.GetRasterColorInterpretation().ToString());
return;
}
if (ds.RasterCount < 3)
{
Console.WriteLine("The number of the raster bands is not enough to run this sample");
System.Environment.Exit(-1);
}
Band greenBand = ds.GetRasterBand(2);
if (greenBand.GetRasterColorInterpretation() != ColorInterp.GCI_GreenBand)
{
Console.WriteLine("Non RGB images are not supported by this sample! ColorInterp = " +
greenBand.GetRasterColorInterpretation().ToString());
return;
}
Band blueBand = ds.GetRasterBand(3);
if (blueBand.GetRasterColorInterpretation() != ColorInterp.GCI_BlueBand)
{
Console.WriteLine("Non RGB images are not supported by this sample! ColorInterp = " +
blueBand.GetRasterColorInterpretation().ToString());
return;
}
int width = redBand.XSize;
int height = redBand.YSize;
// Create a Bitmap to store the GDAL image in
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
DateTime start = DateTime.Now;
byte[] r = new byte[width * height];
byte[] g = new byte[width * height];
byte[] b = new byte[width * height];
redBand.ReadRaster(0, 0, width, height, r, width, height, 0, 0);
greenBand.ReadRaster(0, 0, width, height, g, width, height, 0, 0);
blueBand.ReadRaster(0, 0, width, height, b, width, height, 0, 0);
TimeSpan renderTime = DateTime.Now - start;//计算生成一幅新的栅格图像所需要的时间
Console.WriteLine("SaveBitmapBuffered fetch time: " + renderTime.TotalMilliseconds + " ms");
int i, j;
for (i = 0; i< width; i++)
{
for (j=0; j<height; j++)
{
Color newColor = Color.FromArgb(Convert.ToInt32(r[i+j*width]),Convert.ToInt32(g[i+j*width]), Convert.ToInt32(b[i+j*width]));
bitmap.SetPixel(i, j, newColor);
}
}
bitmap.Save(filename);
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OSGeo.GDAL;
using System.Drawing;
using System.Drawing.Imaging;
namespace GDALRead
{
class Program
{
public static void usage()
{
Console.WriteLine("usage");
System.Environment.Exit(-1);
}
public static void Main(string[] args)
{
if (args.Length < 2) usage();
Console.WriteLine("args包括两个字符串,一个是filename及路径,一个是outfilename及路径");
try
{
Gdal.AllRegister();
Dataset ds = Gdal.Open(args[0],Access.GA_ReadOnly);//读取filename栅格图像
if (ds==null)
{
Console.WriteLine("Can't open " + args[0]);
System.Environment.Exit(-1);
}
Console.WriteLine("raster dataset parameters:");
Console.WriteLine(" Projection:" + ds.GetProjectionRef());
Console.WriteLine(" Rastercount:" + ds.RasterCount);//RasterCount是波段数
Console.WriteLine(" RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")");
/************************************************************************/
/* Get Driver */
/************************************************************************/
Driver drv = ds.GetDriver();
if (drv ==null)
{
Console.WriteLine("Can't get driver");
System.Environment.Exit(-1);
}
Console.WriteLine("using driver" + drv.LongName);
/************************************************************************/
/* Get raster band */
/************************************************************************/
for (int iBand=1;iBand<=ds.RasterCount;iBand++)
{
Band band = ds.GetRasterBand(iBand);
Console.WriteLine("Band" + iBand + ":");
Console.WriteLine(" DataType:" + band.DataType);
Console.WriteLine(" Size (" + band.XSize + "," + band.YSize + ")");
Console.WriteLine(" PaletteInterp: " + band.GetRasterColorInterpretation().ToString()); //调色板图像
}
/************************************************************************/
/* Processing the raster
/************************************************************************/
SaveBitmapBuffered(ds, args[1]);
}
catch (System.Exception ex)
{
Console.WriteLine("Application error: " + ex.Message);
}
Console.ReadLine();
}
private static void SaveBitmapBuffered(Dataset ds, string filename)
{
Band redBand = ds.GetRasterBand(1);
if (redBand.GetRasterColorInterpretation() != ColorInterp.GCI_RedBand)
{
Console.WriteLine("Non RGB images are not supported by this sample! ColorInterp = " +
redBand.GetRasterColorInterpretation().ToString());
return;
}
if (ds.RasterCount < 3)
{
Console.WriteLine("The number of the raster bands is not enough to run this sample");
System.Environment.Exit(-1);
}
Band greenBand = ds.GetRasterBand(2);
if (greenBand.GetRasterColorInterpretation() != ColorInterp.GCI_GreenBand)
{
Console.WriteLine("Non RGB images are not supported by this sample! ColorInterp = " +
greenBand.GetRasterColorInterpretation().ToString());
return;
}
Band blueBand = ds.GetRasterBand(3);
if (blueBand.GetRasterColorInterpretation() != ColorInterp.GCI_BlueBand)
{
Console.WriteLine("Non RGB images are not supported by this sample! ColorInterp = " +
blueBand.GetRasterColorInterpretation().ToString());
return;
}
int width = redBand.XSize;
int height = redBand.YSize;
// Create a Bitmap to store the GDAL image in
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
DateTime start = DateTime.Now;
byte[] r = new byte[width * height];
byte[] g = new byte[width * height];
byte[] b = new byte[width * height];
redBand.ReadRaster(0, 0, width, height, r, width, height, 0, 0);
greenBand.ReadRaster(0, 0, width, height, g, width, height, 0, 0);
blueBand.ReadRaster(0, 0, width, height, b, width, height, 0, 0);
TimeSpan renderTime = DateTime.Now - start;//计算生成一幅新的栅格图像所需要的时间
Console.WriteLine("SaveBitmapBuffered fetch time: " + renderTime.TotalMilliseconds + " ms");
int i, j;
for (i = 0; i< width; i++)
{
for (j=0; j<height; j++)
{
Color newColor = Color.FromArgb(Convert.ToInt32(r[i+j*width]),Convert.ToInt32(g[i+j*width]), Convert.ToInt32(b[i+j*width]));
bitmap.SetPixel(i, j, newColor);
}
}
bitmap.Save(filename);
}
}
}
三 运行结果
我用QQ截了一个RGB的图像(22k),程序运行的结果如图:
另外,在我的GDALRead\bin\Debug目录下新生成了一个一样的,但是.tif的文件(61k).
四 说明
必须说明的是,在原官方的程序中有很多地方提到如GetOverview与GetViewCount等函数。这就涉及到建立栅格金字塔问题,如果其实如果数据不大,或者可以忍受读取,主要就是一种显示数据索引。但作为初学者,我觉得还是不去考虑了,随着学习的深入,以后会有接触。