1 /****************************************************************************** 2 * $Id: GDALReadDirect.cs 13437 2007-12-21 21:02:38Z tamas $ 3 * 4 * Name: GDALDatasetRasterIO.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# GDALDatasetRasterIO 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: GDALDatasetRasterIO {GDAL dataset name} {output file name}"); 58 System.Environment.Exit(-1); 59 } 60 Main(string[] args)61 public static void Main(string[] args) 62 { 63 if (args.Length < 2) usage(); 64 65 // Using early initialization of System.Console 66 Console.WriteLine(""); 67 68 try 69 { 70 /* -------------------------------------------------------------------- */ 71 /* Register driver(s). */ 72 /* -------------------------------------------------------------------- */ 73 Gdal.AllRegister(); 74 75 /* -------------------------------------------------------------------- */ 76 /* Open dataset. */ 77 /* -------------------------------------------------------------------- */ 78 Dataset ds = Gdal.Open( args[0], Access.GA_ReadOnly ); 79 80 if (ds == null) 81 { 82 Console.WriteLine("Can't open " + args[0]); 83 System.Environment.Exit(-1); 84 } 85 86 Console.WriteLine("Raster dataset parameters:"); 87 Console.WriteLine(" Projection: " + ds.GetProjectionRef()); 88 Console.WriteLine(" RasterCount: " + ds.RasterCount); 89 Console.WriteLine(" RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")"); 90 91 /* -------------------------------------------------------------------- */ 92 /* Get driver */ 93 /* -------------------------------------------------------------------- */ 94 Driver drv = ds.GetDriver(); 95 96 if (drv == null) 97 { 98 Console.WriteLine("Can't get driver."); 99 System.Environment.Exit(-1); 100 } 101 102 Console.WriteLine("Using driver " + drv.LongName); 103 104 /* -------------------------------------------------------------------- */ 105 /* Processing the raster */ 106 /* -------------------------------------------------------------------- */ 107 SaveBitmapDirect(args[1], ds, 0, 0, ds.RasterXSize, ds.RasterYSize, ds.RasterXSize, ds.RasterYSize); 108 109 } 110 catch (Exception e) 111 { 112 Console.WriteLine("Application error: " + e.Message); 113 } 114 } 115 SaveBitmapDirect(string filename, Dataset ds, int xOff, int yOff, int width, int height, int imageWidth, int imageHeight)116 private static void SaveBitmapDirect(string filename, Dataset ds, int xOff, int yOff, int width, int height, int imageWidth, int imageHeight) 117 { 118 if (ds.RasterCount == 0) 119 return; 120 121 int[] bandMap = new int[4] { 1, 1, 1, 1 }; 122 int channelCount = 1; 123 bool hasAlpha = false; 124 bool isIndexed = false; 125 int channelSize = 8; 126 ColorTable ct = null; 127 // Evaluate the bands and find out a proper image transfer format 128 for (int i = 0; i < ds.RasterCount; i++) 129 { 130 Band band = ds.GetRasterBand(i + 1); 131 if (Gdal.GetDataTypeSize(band.DataType) > 8) 132 channelSize = 16; 133 switch (band.GetRasterColorInterpretation()) 134 { 135 case ColorInterp.GCI_AlphaBand: 136 channelCount = 4; 137 hasAlpha = true; 138 bandMap[3] = i + 1; 139 break; 140 case ColorInterp.GCI_BlueBand: 141 if (channelCount < 3) 142 channelCount = 3; 143 bandMap[0] = i + 1; 144 break; 145 case ColorInterp.GCI_RedBand: 146 if (channelCount < 3) 147 channelCount = 3; 148 bandMap[2] = i + 1; 149 break; 150 case ColorInterp.GCI_GreenBand: 151 if (channelCount < 3) 152 channelCount = 3; 153 bandMap[1] = i + 1; 154 break; 155 case ColorInterp.GCI_PaletteIndex: 156 ct = band.GetRasterColorTable(); 157 isIndexed = true; 158 bandMap[0] = i + 1; 159 break; 160 case ColorInterp.GCI_GrayIndex: 161 isIndexed = true; 162 bandMap[0] = i + 1; 163 break; 164 default: 165 // we create the bandmap using the dataset ordering by default 166 if (i < 4 && bandMap[i] == 0) 167 { 168 if (channelCount < i) 169 channelCount = i; 170 bandMap[i] = i + 1; 171 } 172 break; 173 } 174 } 175 176 // find out the pixel format based on the gathered information 177 PixelFormat pixelFormat; 178 DataType dataType; 179 int pixelSpace; 180 181 if (isIndexed) 182 { 183 pixelFormat = PixelFormat.Format8bppIndexed; 184 dataType = DataType.GDT_Byte; 185 pixelSpace = 1; 186 } 187 else 188 { 189 if (channelCount == 1) 190 { 191 if (channelSize > 8) 192 { 193 pixelFormat = PixelFormat.Format16bppGrayScale; 194 dataType = DataType.GDT_Int16; 195 pixelSpace = 2; 196 } 197 else 198 { 199 pixelFormat = PixelFormat.Format24bppRgb; 200 channelCount = 3; 201 dataType = DataType.GDT_Byte; 202 pixelSpace = 3; 203 } 204 } 205 else 206 { 207 if (hasAlpha) 208 { 209 if (channelSize > 8) 210 { 211 pixelFormat = PixelFormat.Format64bppArgb; 212 dataType = DataType.GDT_UInt16; 213 pixelSpace = 8; 214 } 215 else 216 { 217 pixelFormat = PixelFormat.Format32bppArgb; 218 dataType = DataType.GDT_Byte; 219 pixelSpace = 4; 220 } 221 channelCount = 4; 222 } 223 else 224 { 225 if (channelSize > 8) 226 { 227 pixelFormat = PixelFormat.Format48bppRgb; 228 dataType = DataType.GDT_UInt16; 229 pixelSpace = 6; 230 } 231 else 232 { 233 pixelFormat = PixelFormat.Format24bppRgb; 234 dataType = DataType.GDT_Byte; 235 pixelSpace = 3; 236 } 237 channelCount = 3; 238 } 239 } 240 } 241 242 243 // Create a Bitmap to store the GDAL image in 244 Bitmap bitmap = new Bitmap(imageWidth, imageHeight, pixelFormat); 245 246 if (isIndexed) 247 { 248 // setting up the color table 249 if (ct != null) 250 { 251 int iCol = ct.GetCount(); 252 ColorPalette pal = bitmap.Palette; 253 for (int i = 0; i < iCol; i++) 254 { 255 ColorEntry ce = ct.GetColorEntry(i); 256 pal.Entries[i] = Color.FromArgb(ce.c4, ce.c1, ce.c2, ce.c3); 257 } 258 bitmap.Palette = pal; 259 } 260 else 261 { 262 // grayscale 263 ColorPalette pal = bitmap.Palette; 264 for (int i = 0; i < 256; i++) 265 pal.Entries[i] = Color.FromArgb(255, i, i, i); 266 bitmap.Palette = pal; 267 } 268 } 269 270 // Use GDAL raster reading methods to read the image data directly into the Bitmap 271 BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadWrite, pixelFormat); 272 273 try 274 { 275 int stride = bitmapData.Stride; 276 IntPtr buf = bitmapData.Scan0; 277 278 ds.ReadRaster(xOff, yOff, width, height, buf, imageWidth, imageHeight, dataType, 279 channelCount, bandMap, pixelSpace, stride, 1); 280 } 281 finally 282 { 283 bitmap.UnlockBits(bitmapData); 284 } 285 286 bitmap.Save(filename); 287 } 288 }