1 /******************************************************************************
2  * $Id: GDALReadDirect.cs d663b6c3d575bb6dae66de854ca6212c38249b79 2020-12-21 14:05:32 -0800 Chris Zielin $
3  *
4  * Name:     GDALReadDirect.cs
5  * Project:  GDAL CSharp Interface
6  * Purpose:  A sample app to read GDAL raster data directly to a C# bitmap.
7  * Author:   Tamas Szekeres, szekerest@gmail.com
8  *
9  ******************************************************************************
10  * Copyright (c) 2007, Tamas Szekeres
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  *****************************************************************************/
30 
31 using System;
32 using System.Drawing;
33 using System.Drawing.Imaging;
34 
35 using OSGeo.GDAL;
36 
37 
38 /**
39 
40  * <p>Title: GDAL C# GDALRead example.</p>
41  * <p>Description: A sample app to read GDAL raster data directly to a C# bitmap.</p>
42  * @author Tamas Szekeres (szekerest@gmail.com)
43  * @version 1.0
44  */
45 
46 
47 
48 /// <summary>
49 /// A C# based sample to read GDAL raster data directly to a C# bitmap.
50 /// </summary>
51 
52 class GDALReadDirect {
53 
usage()54 	public static void usage()
55 
56 	{
57 		Console.WriteLine("usage: gdalread {GDAL dataset name} {output file name} {overview}");
58 		System.Environment.Exit(-1);
59 	}
60 
Main(string[] args)61     public static void Main(string[] args)
62     {
63 
64         int iOverview = -1;
65         if (args.Length < 2) usage();
66         if (args.Length == 3) iOverview = int.Parse(args[2]);
67 
68         // Using early initialization of System.Console
69         Console.WriteLine("");
70 
71         try
72         {
73             /* -------------------------------------------------------------------- */
74             /*      Register driver(s).                                             */
75             /* -------------------------------------------------------------------- */
76             Gdal.AllRegister();
77 
78             /* -------------------------------------------------------------------- */
79             /*      Open dataset.                                                   */
80             /* -------------------------------------------------------------------- */
81             Dataset ds = Gdal.Open( args[0], Access.GA_ReadOnly );
82 
83             if (ds == null)
84             {
85                 Console.WriteLine("Can't open " + args[0]);
86                 System.Environment.Exit(-1);
87             }
88 
89             Console.WriteLine("Raster dataset parameters:");
90             Console.WriteLine("  Projection: " + ds.GetProjectionRef());
91             Console.WriteLine("  RasterCount: " + ds.RasterCount);
92             Console.WriteLine("  RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")");
93 
94             /* -------------------------------------------------------------------- */
95             /*      Get driver                                                      */
96             /* -------------------------------------------------------------------- */
97             Driver drv = ds.GetDriver();
98 
99             if (drv == null)
100             {
101                 Console.WriteLine("Can't get driver.");
102                 System.Environment.Exit(-1);
103             }
104 
105             Console.WriteLine("Using driver " + drv.LongName);
106 
107             /* -------------------------------------------------------------------- */
108             /*      Get raster band                                                 */
109             /* -------------------------------------------------------------------- */
110             for (int iBand = 1; iBand <= ds.RasterCount; iBand++)
111             {
112                 Band band = ds.GetRasterBand(iBand);
113                 Console.WriteLine("Band " + iBand + " :");
114                 Console.WriteLine("   DataType: " + band.DataType);
115                 Console.WriteLine("   Size (" + band.XSize + "," + band.YSize + ")");
116                 Console.WriteLine("   PaletteInterp: " + band.GetRasterColorInterpretation().ToString());
117 
118                 for (int iOver = 0; iOver < band.GetOverviewCount(); iOver++)
119                 {
120                     Band over = band.GetOverview(iOver);
121                     Console.WriteLine("      OverView " + iOver + " :");
122                     Console.WriteLine("         DataType: " + over.DataType);
123                     Console.WriteLine("         Size (" + over.XSize + "," + over.YSize + ")");
124                     Console.WriteLine("         PaletteInterp: " + over.GetRasterColorInterpretation().ToString());
125                 }
126             }
127 
128             /* -------------------------------------------------------------------- */
129             /*      Processing the raster                                           */
130             /* -------------------------------------------------------------------- */
131             SaveBitmapDirect(ds, args[1], iOverview);
132 
133         }
134         catch (Exception e)
135         {
136             Console.WriteLine("Application error: " + e.Message);
137         }
138     }
139 
SaveBitmapDirect(Dataset ds, string filename, int iOverview)140     private static void SaveBitmapDirect(Dataset ds, string filename, int iOverview)
141     {
142         // Get the GDAL Band objects from the Dataset
143         Band redBand = ds.GetRasterBand(1);
144 
145         if (redBand.GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex)
146         {
147             SaveBitmapPaletteDirect(ds, filename, iOverview);
148             return;
149         }
150 
151         if (redBand.GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex)
152         {
153             SaveBitmapGrayDirect(ds, filename, iOverview);
154             return;
155         }
156 
157         if (ds.RasterCount < 3)
158         {
159             Console.WriteLine("The number of the raster bands is not enough to run this sample");
160             System.Environment.Exit(-1);
161         }
162 
163         if (iOverview >= 0 && redBand.GetOverviewCount() > iOverview)
164             redBand = redBand.GetOverview(iOverview);
165 
166         Band greenBand = ds.GetRasterBand(2);
167 
168         if (iOverview >= 0 && greenBand.GetOverviewCount() > iOverview)
169             greenBand = greenBand.GetOverview(iOverview);
170 
171         Band blueBand = ds.GetRasterBand(3);
172 
173         if (iOverview >= 0 && blueBand.GetOverviewCount() > iOverview)
174             blueBand = blueBand.GetOverview(iOverview);
175 
176         // Get the width and height of the Dataset
177         int width = redBand.XSize;
178         int height = redBand.YSize;
179 
180         // Create a Bitmap to store the GDAL image in
181         Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
182 
183         DateTime start = DateTime.Now;
184 
185         // Use GDAL raster reading methods to read the image data directly into the Bitmap
186         BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
187 
188         try
189         {
190             int stride = bitmapData.Stride;
191             IntPtr buf = bitmapData.Scan0;
192 
193             blueBand.ReadRaster(0, 0, width, height, buf, width, height, DataType.GDT_Byte, 4, stride);
194             greenBand.ReadRaster(0, 0, width, height, new IntPtr(buf.ToInt64()+1), width, height, DataType.GDT_Byte, 4, stride);
195             redBand.ReadRaster(0, 0, width, height, new IntPtr(buf.ToInt64()+2), width, height, DataType.GDT_Byte, 4, stride);
196             TimeSpan renderTime = DateTime.Now - start;
197             Console.WriteLine("SaveBitmapDirect fetch time: " + renderTime.TotalMilliseconds + " ms");
198         }
199         finally
200         {
201             bitmap.UnlockBits(bitmapData);
202         }
203 
204         bitmap.Save(filename);
205     }
206 
SaveBitmapPaletteDirect(Dataset ds, string filename, int iOverview)207     private static void SaveBitmapPaletteDirect(Dataset ds, string filename, int iOverview)
208     {
209         // Get the GDAL Band objects from the Dataset
210         Band band = ds.GetRasterBand(1);
211         if (iOverview >= 0 && band.GetOverviewCount() > iOverview)
212             band = band.GetOverview(iOverview);
213 
214         ColorTable ct = band.GetRasterColorTable();
215         if (ct == null)
216         {
217             Console.WriteLine("   Band has no color table!");
218             return;
219         }
220 
221         if (ct.GetPaletteInterpretation() != PaletteInterp.GPI_RGB)
222         {
223             Console.WriteLine("   Only RGB palette interp is supported by this sample!");
224             return;
225         }
226 
227         // Get the width and height of the Dataset
228         int width = band.XSize;
229         int height = band.YSize;
230 
231         // Create a Bitmap to store the GDAL image in
232         Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
233 
234         DateTime start = DateTime.Now;
235 
236         byte[] r = new byte[width * height];
237 
238         band.ReadRaster(0, 0, width, height, r, width, height, 0, 0);
239         // Use GDAL raster reading methods to read the image data directly into the Bitmap
240         BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
241 
242         try
243         {
244             int iCol = ct.GetCount();
245             ColorPalette pal = bitmap.Palette;
246             for (int i = 0; i < iCol; i++)
247             {
248                 ColorEntry ce = ct.GetColorEntry(i);
249                 pal.Entries[i] = Color.FromArgb(ce.c4, ce.c1, ce.c2, ce.c3);
250             }
251             bitmap.Palette = pal;
252 
253             int stride = bitmapData.Stride;
254             IntPtr buf = bitmapData.Scan0;
255 
256             band.ReadRaster(0, 0, width, height, buf, width, height, DataType.GDT_Byte, 1, stride);
257             TimeSpan renderTime = DateTime.Now - start;
258             Console.WriteLine("SaveBitmapDirect fetch time: " + renderTime.TotalMilliseconds + " ms");
259         }
260         finally
261         {
262             bitmap.UnlockBits(bitmapData);
263         }
264 
265         bitmap.Save(filename);
266     }
267 
SaveBitmapGrayDirect(Dataset ds, string filename, int iOverview)268     private static void SaveBitmapGrayDirect(Dataset ds, string filename, int iOverview)
269     {
270         // Get the GDAL Band objects from the Dataset
271         Band band = ds.GetRasterBand(1);
272         if (iOverview >= 0 && band.GetOverviewCount() > iOverview)
273             band = band.GetOverview(iOverview);
274 
275         // Get the width and height of the Dataset
276         int width = band.XSize;
277         int height = band.YSize;
278 
279         // Create a Bitmap to store the GDAL image in
280         Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
281 
282         DateTime start = DateTime.Now;
283 
284         byte[] r = new byte[width * height];
285 
286         band.ReadRaster(0, 0, width, height, r, width, height, 0, 0);
287         // Use GDAL raster reading methods to read the image data directly into the Bitmap
288         BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
289 
290         try
291         {
292             ColorPalette pal = bitmap.Palette;
293             for(int i = 0; i < 256; i++)
294                 pal.Entries[i] = Color.FromArgb( 255, i, i, i );
295             bitmap.Palette = pal;
296 
297             int stride = bitmapData.Stride;
298             IntPtr buf = bitmapData.Scan0;
299 
300             band.ReadRaster(0, 0, width, height, buf, width, height, DataType.GDT_Byte, 1, stride);
301             TimeSpan renderTime = DateTime.Now - start;
302             Console.WriteLine("SaveBitmapDirect fetch time: " + renderTime.TotalMilliseconds + " ms");
303         }
304         finally
305         {
306             bitmap.UnlockBits(bitmapData);
307         }
308 
309         bitmap.Save(filename);
310     }
311 }