root/trunk/gdal/swig/csharp/apps/GDALAdjustContrast.cs

Revision 14383, 12.5 kB (checked in by tamas, 7 months ago)

Added the GDALAdjustContrast sample to demonstrate the image correction at the C# side.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /******************************************************************************
2  * $Id$
3  *
4  * Name:     GDALAdjustContrast.cs
5  * Project:  GDAL CSharp Interface
6  * Purpose:  A sample app to demonstrate how to read the dataset into the
7  *           memory, adjust the contrast of the image and write back to the
8  *           dataset persistently.
9  * Author:   Tamas Szekeres, szekerest@gmail.com
10  *
11  ******************************************************************************
12  * Copyright (c) 2007, Tamas Szekeres
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining a
15  * copy of this software and associated documentation files (the "Software"),
16  * to deal in the Software without restriction, including without limitation
17  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18  * and/or sell copies of the Software, and to permit persons to whom the
19  * Software is furnished to do so, subject to the following conditions:
20  *
21  * The above copyright notice and this permission notice shall be included
22  * in all copies or substantial portions of the Software.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30  * DEALINGS IN THE SOFTWARE.
31  *****************************************************************************/
32
33 using System;
34 using System.Drawing;
35 using System.Drawing.Imaging;
36 using System.Drawing.Drawing2D;
37 using OSGeo.GDAL;
38
39 /**
40  * <p>Title: GDAL C# GDALAdjustContrast example.</p>
41  * <p>Description: A sample app to demonstrate how to read the dataset into the
42  * memory, adjust the contrast of the image and write back to the dataset persistently.</p>
43  * @author Tamas Szekeres (szekerest@gmail.com)
44  * @version 1.0
45  */
46
47
48
49 /// <summary>
50 /// A sample app to demonstrate how to read the dataset into the
51 /// memory, adjust the contrast of the image and write back to the dataset persistently.
52 /// </summary>
53
54 class GDALAdjustContrast {
55        
56         public static void usage()
57
58         {
59         Console.WriteLine("usage: GDALAdjustContrast {dataset name} {contrast ratio}");
60                 System.Environment.Exit(-1);
61         }
62
63
64     // bitmap parameters
65     static int[] bandMap;
66     static ColorTable ct;
67     static int channelCount;
68     static bool hasAlpha;
69     static bool isPremultiplied;
70     static bool isIndexed;
71     static int channelSize;
72     static PixelFormat pixelFormat;
73     static DataType dataType;
74     static int pixelSpace;
75
76     public static void Main(string[] args)
77     {
78
79         if (args.Length != 2) usage();
80
81         // Using early initialization of System.Console
82         Console.WriteLine("Adjusting the image: " + args[0]);
83
84         try
85         {
86             float contrastRatio = float.Parse(args[1]);
87             /* -------------------------------------------------------------------- */
88             /*      Register driver(s).                                             */
89             /* -------------------------------------------------------------------- */
90             Gdal.AllRegister();
91
92             /* -------------------------------------------------------------------- */
93             /*      Open dataset.                                                   */
94             /* -------------------------------------------------------------------- */
95             Dataset ds = Gdal.Open(args[0], Access.GA_Update);
96                
97             if (ds == null)
98             {
99                 Console.WriteLine("Can't open " + args[0]);
100                 System.Environment.Exit(-1);
101             }
102
103             Bitmap bmp = CreateCompatibleBitmap(ds, ds.RasterXSize, ds.RasterYSize);
104             LoadBitmapDirect(ds, bmp, 0, 0, ds.RasterXSize, ds.RasterYSize, ds.RasterXSize, ds.RasterYSize, 0);
105             Bitmap newBitmap = (Bitmap)bmp.Clone();
106
107             //create the ColorMatrix
108             float[][] colormatrix = new float[][]
109               {
110                  new float[] {contrastRatio, 0, 0, 0, 0},
111                  new float[] {0, contrastRatio, 0, 0, 0},
112                  new float[] {0, 0, contrastRatio, 0, 0},
113                  new float[] {0, 0, 0, 1, 0},
114                  new float[] {0, 0, 0, 0, 1}
115               };
116             ColorMatrix colorMatrix = new ColorMatrix(colormatrix);
117
118             //create the image attributes
119             ImageAttributes attributes = new ImageAttributes();
120
121             //set the color matrix attribute
122             attributes.SetColorMatrix(colorMatrix);
123
124             //get a graphics object from the new image
125             Graphics g = Graphics.FromImage(newBitmap);
126             //draw the original image on the new image
127             g.DrawImage(bmp,
128                new Rectangle(0, 0, bmp.Width, bmp.Height),
129                0, 0, bmp.Width, bmp.Height,
130                GraphicsUnit.Pixel, attributes);
131
132             SaveBitmapDirect(ds, newBitmap, 0, 0, ds.RasterXSize, ds.RasterYSize, ds.RasterXSize, ds.RasterYSize);
133
134             ds.FlushCache();
135
136         }
137         catch (Exception e)
138         {
139             Console.WriteLine("Application error: " + e.Message);
140         }
141     }
142
143     private static Bitmap CreateCompatibleBitmap(Dataset ds, int imageWidth, int imageHeight)
144     {
145         if (ds.RasterCount == 0)
146             return null;
147
148         bandMap = new int[4] { 1, 1, 1, 1 };
149         channelCount = 1;
150         hasAlpha = false;
151         isPremultiplied = false;
152         isIndexed = false;
153         channelSize = 8;
154         // Evaluate the bands and find out a proper image transfer format
155         for (int i = 0; i < ds.RasterCount; i++)
156         {
157             Band band = ds.GetRasterBand(i + 1);
158             if (Gdal.GetDataTypeSize(band.DataType) > 8)
159                 channelSize = 16;
160
161             // retrieving the premultiplied alpha flag
162             string[] metadata = band.GetMetadata("");
163             for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
164             {
165                 if (metadata[iMeta].StartsWith("PREMULTIPLIED_ALPHA"))
166                     isPremultiplied = true;
167             }
168
169             switch (band.GetRasterColorInterpretation())
170             {
171                 case ColorInterp.GCI_AlphaBand:
172                     channelCount = 4;
173                     hasAlpha = true;
174                     bandMap[3] = i + 1;
175                     break;
176                 case ColorInterp.GCI_BlueBand:
177                     if (channelCount < 3)
178                         channelCount = 3;
179                     bandMap[0] = i + 1;
180                     break;
181                 case ColorInterp.GCI_RedBand:
182                     if (channelCount < 3)
183                         channelCount = 3;
184                     bandMap[2] = i + 1;
185                     break;
186                 case ColorInterp.GCI_GreenBand:
187                     if (channelCount < 3)
188                         channelCount = 3;
189                     bandMap[1] = i + 1;
190                     break;
191                 case ColorInterp.GCI_PaletteIndex:
192                     ct = band.GetRasterColorTable();
193                     isIndexed = true;
194                     bandMap[0] = i + 1;
195                     break;
196                 case ColorInterp.GCI_GrayIndex:
197                     isIndexed = true;
198                     bandMap[0] = i + 1;
199                     break;
200                 default:
201                     // we create the bandmap using the dataset ordering by default
202                     if (i < 4 && bandMap[i] == 0)
203                     {
204                         if (channelCount < i)
205                             channelCount = i;
206                         bandMap[i] = i + 1;
207                     }
208                     break;
209             }
210         }
211
212         // find out the pixel format based on the gathered information
213         if (isIndexed)
214         {
215             pixelFormat = PixelFormat.Format8bppIndexed;
216             dataType = DataType.GDT_Byte;
217             pixelSpace = 1;
218         }
219         else
220         {
221             if (channelCount == 1)
222             {
223                 if (channelSize > 8)
224                 {
225                     pixelFormat = PixelFormat.Format16bppGrayScale;
226                     dataType = DataType.GDT_Int16;
227                     pixelSpace = 2;
228                 }
229                 else
230                 {
231                     pixelFormat = PixelFormat.Format24bppRgb;
232                     channelCount = 3;
233                     dataType = DataType.GDT_Byte;
234                     pixelSpace = 3;
235                 }
236             }
237             else
238             {
239                 if (hasAlpha)
240                 {
241                     if (channelSize > 8)
242                     {
243                         if (isPremultiplied)
244                             pixelFormat = PixelFormat.Format64bppArgb;
245                         else
246                             pixelFormat = PixelFormat.Format64bppPArgb;
247                         dataType = DataType.GDT_UInt16;
248                         pixelSpace = 8;
249                     }
250                     else
251                     {
252                         if (isPremultiplied)
253                             pixelFormat = PixelFormat.Format32bppPArgb;
254                         else
255                             pixelFormat = PixelFormat.Format32bppArgb;
256                         dataType = DataType.GDT_Byte;
257                         pixelSpace = 4;
258                     }
259                     channelCount = 4;
260                 }
261                 else
262                 {
263                     if (channelSize > 8)
264                     {
265                         pixelFormat = PixelFormat.Format48bppRgb;
266                         dataType = DataType.GDT_UInt16;
267                         pixelSpace = 6;
268                     }
269                     else
270                     {
271                         pixelFormat = PixelFormat.Format24bppRgb;
272                         dataType = DataType.GDT_Byte;
273                         pixelSpace = 3;
274                     }
275                     channelCount = 3;
276                 }
277             }
278         }
279
280
281         // Create a Bitmap to store the GDAL image in
282         return new Bitmap(imageWidth, imageHeight, pixelFormat);
283     }
284
285     private static void LoadBitmapDirect(Dataset ds, Bitmap bitmap, int xOff, int yOff, int width, int height, int imageWidth, int imageHeight, int iOverview)
286     {
287         if (isIndexed)
288         {
289             // setting up the color table
290             if (ct != null)
291             {
292                 int iCol = ct.GetCount();
293                 ColorPalette pal = bitmap.Palette;
294                 for (int i = 0; i < iCol; i++)
295                 {
296                     ColorEntry ce = ct.GetColorEntry(i);
297                     pal.Entries[i] = Color.FromArgb(ce.c4, ce.c1, ce.c2, ce.c3);
298                 }
299                 bitmap.Palette = pal;
300             }
301             else
302             {
303                 // grayscale
304                 ColorPalette pal = bitmap.Palette;
305                 for (int i = 0; i < 256; i++)
306                     pal.Entries[i] = Color.FromArgb(255, i, i, i);
307                 bitmap.Palette = pal;
308             }
309         }
310
311         // Use GDAL raster reading methods to read the image data directly into the Bitmap
312         BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadWrite, pixelFormat);
313
314         try
315         {
316             int stride = bitmapData.Stride;
317             IntPtr buf = bitmapData.Scan0;
318
319             ds.ReadRaster(xOff, yOff, width, height, buf, imageWidth, imageHeight, dataType,
320                 channelCount, bandMap, pixelSpace, stride, 1);
321         }
322         finally
323         {
324             bitmap.UnlockBits(bitmapData);
325         }
326     }
327
328     private static void SaveBitmapDirect(Dataset ds, Bitmap bitmap, int xOff, int yOff, int width, int height, int imageWidth, int imageHeight)
329     {
330         if (bitmap != null)
331         {
332             if (isIndexed)
333             {
334                 // TODO: setting up the color table
335             }
336
337             // Use GDAL writing method to write the image data directly from the Bitmap
338             BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadWrite, pixelFormat);
339
340             try
341             {
342                 int stride = bitmapData.Stride;
343                 IntPtr buf = bitmapData.Scan0;
344
345                 ds.WriteRaster(xOff, yOff, width, height, buf, imageWidth, imageHeight, dataType,
346                     channelCount, bandMap, pixelSpace, stride, 1);
347             }
348             finally
349             {
350                 bitmap.UnlockBits(bitmapData);
351             }
352         }
353     }
354 }
Note: See TracBrowser for help on using the browser.