public static void WriteBitmapAsGeotiff(Bitmap bmp, Rectangle bounds, string target_path) { if (!GetGdalDrivers()) { return; } // set up MEM driver to read bitmap data int bandCount = 1; int pixelOffset = 1; DataType dataType = DataType.GDT_Byte; int[] band2ptroffset = null; switch (bmp.PixelFormat) { case PixelFormat.Format16bppGrayScale: dataType = DataType.GDT_Int16; bandCount = 1; pixelOffset = 2; break; case PixelFormat.Format24bppRgb: dataType = DataType.GDT_Byte; bandCount = 3; pixelOffset = 3; break; case PixelFormat.Format32bppArgb: dataType = DataType.GDT_Byte; //bandCount = 4; // This was the band count, but the order is wrong bandCount = 3; band2ptroffset = new int[] { 3, 2, 1, 0 }; pixelOffset = 4; break; case PixelFormat.Format48bppRgb: dataType = DataType.GDT_UInt16; bandCount = 3; pixelOffset = 6; break; case PixelFormat.Format64bppArgb: dataType = DataType.GDT_UInt16; bandCount = 4; pixelOffset = 8; break; case PixelFormat.Format8bppIndexed: dataType = DataType.GDT_Byte; bandCount = 1; pixelOffset = 1; break; default: Console.WriteLine("Invalid pixel format " + bmp.PixelFormat.ToString()); break; } // Use GDAL raster reading methods to read the image data directly into the Bitmap BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); int stride = bitmapData.Stride; IntPtr buf = bitmapData.Scan0; try { Dataset ds = _memory_driver.Create("", bmp.Width, bmp.Height, 0, dataType, null); var transform = GetAffineTransformOfBounds(bounds); ds.SetGeoTransform(transform); ds.SetProjection(ToWkt(dst_wkt)); //var color_interp = new ColorInterp[] { ColorInterp.GCI_AlphaBand, ColorInterp.GCI_RedBand, ColorInterp.GCI_GreenBand, ColorInterp.GCI_BlueBand }; // add bands in a reverse order for (int i = 1; i <= bandCount; i++) { // original CPLErr err; if (band2ptroffset == null) { err = ds.AddBand(dataType, new string[] { "DATAPOINTER=" + Convert.ToString(buf.ToInt64() + bandCount - i), "PIXELOFFSET=" + pixelOffset, "LINEOFFSET=" + stride }); } else { err = ds.AddBand(dataType, new string[] { "DATAPOINTER=" + Convert.ToString(buf.ToInt64() + band2ptroffset[i]), "PIXELOFFSET=" + pixelOffset, "LINEOFFSET=" + stride }); } if (err != CPLErr.CE_None) { Console.WriteLine($"Error adding band to {target_path}"); } } if (bmp.PixelFormat == PixelFormat.Format8bppIndexed) { var ct1 = new ColorTable(PaletteInterp.GPI_RGB); var band = ds.GetRasterBand(1); var ct = band.GetRasterColorTable(); Console.WriteLine($"color table count={ct.GetCount()}"); } if (File.Exists(target_path)) { File.Delete(target_path); } var ds_copy = _geotif_driver.CreateCopy(target_path, ds, 0, null, null, null); ds_copy.FlushCache(); ds_copy.Dispose(); ds.Dispose(); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { bmp.UnlockBits(bitmapData); } }
public static void Main(string[] args) { if (args.Length != 1) { usage(); } Gdal.AllRegister(); Bitmap bmp = new Bitmap(args[0]); // set up MEM driver to read bitmap data int bandCount = 1; int pixelOffset = 1; DataType dataType = DataType.GDT_Byte; switch (bmp.PixelFormat) { case PixelFormat.Format16bppGrayScale: dataType = DataType.GDT_Int16; bandCount = 1; pixelOffset = 2; break; case PixelFormat.Format24bppRgb: dataType = DataType.GDT_Byte; bandCount = 3; pixelOffset = 3; break; case PixelFormat.Format32bppArgb: dataType = DataType.GDT_Byte; bandCount = 4; pixelOffset = 4; break; case PixelFormat.Format48bppRgb: dataType = DataType.GDT_UInt16; bandCount = 3; pixelOffset = 6; break; case PixelFormat.Format64bppArgb: dataType = DataType.GDT_UInt16; bandCount = 4; pixelOffset = 8; break; default: Console.WriteLine("Invalid pixel format " + bmp.PixelFormat.ToString()); break; } // Use GDAL raster reading methods to read the image data directly into the Bitmap BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); int stride = bitmapData.Stride; IntPtr buf = bitmapData.Scan0; try { Driver drvmem = Gdal.GetDriverByName("MEM"); // create a MEM dataset Dataset ds = drvmem.Create("", bmp.Width, bmp.Height, 0, dataType, null); // add bands in a reverse order for (int i = 1; i <= bandCount; i++) { ds.AddBand(dataType, new string[] { "DATAPOINTER=" + Convert.ToString(buf.ToInt64() + bandCount - i), "PIXELOFFSET=" + pixelOffset, "LINEOFFSET=" + stride }); } // display parameters Console.WriteLine("Raster dataset parameters:"); Console.WriteLine(" RasterCount: " + ds.RasterCount); Console.WriteLine(" RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")"); // write dataset to tif file Driver drv = Gdal.GetDriverByName("GTiff"); if (drv == null) { Console.WriteLine("Can't get driver."); System.Environment.Exit(-1); } drv.CreateCopy("sample2.tif", ds, 0, null, null, null); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { bmp.UnlockBits(bitmapData); } }