private static void SaveBitmapDirect(string filename, Dataset ds, int xOff, int yOff, int width, int height, int imageWidth, int imageHeight) { if (ds.RasterCount == 0) return; int[] bandMap = new int[4] { 1, 1, 1, 1 }; int channelCount = 1; bool hasAlpha = false; bool isIndexed = false; int channelSize = 8; ColorTable ct = null; // Evaluate the bands and find out a proper image transfer format for (int i = 0; i < ds.RasterCount; i++) { Band band = ds.GetRasterBand(i + 1); if (Gdal.GetDataTypeSize(band.DataType) > 8) channelSize = 16; switch (band.GetRasterColorInterpretation()) { case ColorInterp.GCI_AlphaBand: channelCount = 4; hasAlpha = true; bandMap[3] = i + 1; break; case ColorInterp.GCI_BlueBand: if (channelCount < 3) channelCount = 3; bandMap[0] = i + 1; break; case ColorInterp.GCI_RedBand: if (channelCount < 3) channelCount = 3; bandMap[2] = i + 1; break; case ColorInterp.GCI_GreenBand: if (channelCount < 3) channelCount = 3; bandMap[1] = i + 1; break; case ColorInterp.GCI_PaletteIndex: ct = band.GetRasterColorTable(); isIndexed = true; bandMap[0] = i + 1; break; case ColorInterp.GCI_GrayIndex: isIndexed = true; bandMap[0] = i + 1; break; default: // we create the bandmap using the dataset ordering by default if (i < 4 && bandMap[i] == 0) { if (channelCount < i) channelCount = i; bandMap[i] = i + 1; } break; } } // find out the pixel format based on the gathered information PixelFormat pixelFormat; DataType dataType; int pixelSpace; if (isIndexed) { pixelFormat = PixelFormat.Format8bppIndexed; dataType = DataType.GDT_Byte; pixelSpace = 1; } else { if (channelCount == 1) { if (channelSize > 8) { pixelFormat = PixelFormat.Format16bppGrayScale; dataType = DataType.GDT_Int16; pixelSpace = 2; } else { pixelFormat = PixelFormat.Format24bppRgb; channelCount = 3; dataType = DataType.GDT_Byte; pixelSpace = 3; } } else { if (hasAlpha) { if (channelSize > 8) { pixelFormat = PixelFormat.Format64bppArgb; dataType = DataType.GDT_UInt16; pixelSpace = 8; } else { pixelFormat = PixelFormat.Format32bppArgb; dataType = DataType.GDT_Byte; pixelSpace = 4; } channelCount = 4; } else { if (channelSize > 8) { pixelFormat = PixelFormat.Format48bppRgb; dataType = DataType.GDT_UInt16; pixelSpace = 6; } else { pixelFormat = PixelFormat.Format24bppRgb; dataType = DataType.GDT_Byte; pixelSpace = 3; } channelCount = 3; } } } // Create a Bitmap to store the GDAL image in Bitmap bitmap = new Bitmap(imageWidth, imageHeight, pixelFormat); if (isIndexed) { // setting up the color table if (ct != null) { int iCol = ct.GetCount(); ColorPalette pal = bitmap.Palette; for (int i = 0; i < iCol; i++) { ColorEntry ce = ct.GetColorEntry(i); pal.Entries[i] = Color.FromArgb(ce.c4, ce.c1, ce.c2, ce.c3); } bitmap.Palette = pal; } else { // grayscale ColorPalette pal = bitmap.Palette; for (int i = 0; i < 256; i++) pal.Entries[i] = Color.FromArgb(255, i, i, i); bitmap.Palette = pal; } } // Use GDAL raster reading methods to read the image data directly into the Bitmap BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadWrite, pixelFormat); try { int stride = bitmapData.Stride; IntPtr buf = bitmapData.Scan0; ds.ReadRaster(xOff, yOff, width, height, buf, imageWidth, imageHeight, dataType, channelCount, bandMap, pixelSpace, stride, 1); } finally { bitmap.UnlockBits(bitmapData); } bitmap.Save(filename); }
public new TerrainTile GetTerrainTile(double latitude, double longitude, double samplesPerDegree) { //Get Empty Terrain Tile TerrainTile tt = base.GetTerrainTile(latitude, longitude, samplesPerDegree); //Populate target .bil file with data from DataSet string cachefile = tt.TerrainTileFilePath; //work out lines and pixels to extract from VRT int startpixel = (int)Math.Floor((tt.West - m_transform[0]) / m_transform[1]); int endpixel = (int)Math.Ceiling((tt.East - m_transform[0]) / m_transform[1]); int startline = (int)Math.Floor((tt.North - m_transform[3]) / m_transform[5]); int endline = (int)Math.Ceiling((tt.South - m_transform[3]) / m_transform[5]); int xsize = endpixel - startpixel; int ysize = endline - startline; //Allow partial raster access for beyond edge cases int realstartpixel = Math.Max(0, startpixel); int realstartline = Math.Max(0, startline); int realendpixel = Math.Min(m_pixels, endpixel); int realendline = Math.Min(m_lines, endline); //Scale target window in case of partial access int realxsize = realendpixel - realstartpixel; int realysize = realendline - realstartline; //Scale buffer window int bufxsize = (int)Math.Round(256.0 * (double)realxsize / (double)xsize); int bufysize = (int)Math.Round(256.0 * (double)realysize / (double)ysize); int xoff = (int)Math.Round(256.0 * (double)(realstartpixel - startpixel) / (double)xsize); int yoff = (int)Math.Round(256.0 * (double)(realstartline - startline) / (double)ysize); int totalbuf = bufxsize * bufysize; //use pixel space and line space instead of separate buffers Int16[] dembuffer = new Int16[totalbuf]; //extract data from vrt try { m_dataset.GetRasterBand(1).ReadRaster(realstartpixel, realstartline, realxsize, realysize, dembuffer, bufxsize, bufysize, 0, 0); } catch { Console.WriteLine("Raster Could not be accessed"); } //write out cache file Driver memdriver = Gdal.GetDriverByName("ENVI"); string[] options = new string[0]; //TODO: Add compression OSGeo.GDAL.Dataset tile_ds = memdriver.Create(cachefile, 256, 256, 1, (DataType)OSGeo.GDAL.GdalConst.GDT_Int16, options); tile_ds.GetRasterBand(1).WriteRaster(xoff, yoff, bufxsize, bufysize, dembuffer, bufxsize, bufysize, 0, 0); tile_ds.Dispose(); return(tt); }
public double [] FetchDataFromFile(string filename) { try { OSGeo.GDAL.Gdal.AllRegister(); OSGeo.GDAL.Dataset dataset = Gdal.Open(filename, Access.GA_ReadOnly); if (dataset == null) { Console.WriteLine("Read file was failed!"); } int width = dataset.RasterXSize; int height = dataset.RasterYSize; Band band1 = dataset.GetRasterBand(1); double[] data = new double[width * height]; band1.ReadRaster(0, 0, width, height, data, width, height, 0, 0); return(data); } catch (Exception ex) { return(null); //Console.WriteLine("Read data was failed!"); //Console.WriteLine("Error: " + ex.Message); } }
/// <summary> /// 数据保存 /// </summary> public void Save() { try { OSGeo.GDAL.Gdal.AllRegister(); _dataSet = OSGeo.GDAL.Gdal.Open(_fileName, OSGeo.GDAL.Access.GA_Update); _band1 = _dataSet.GetRasterBand(1); CPLErr err1 = _band1.WriteRaster(0, 0, _resultInfo.Width, _resultInfo.Height, _pixels1, _resultInfo.Width, _resultInfo.Height, 0, 0); _dataSet.Dispose(); _band1.Dispose(); } catch (Exception ex) { throw new Exception("数据写入失败。" + ex.Message); } }
/// <summary> /// This creates a bitmap object from raster data at specific locations in the raster. /// </summary> /// <param name="band"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="startx"></param> /// <param name="starty"></param> /// <param name="readw"></param> /// <param name="readh"></param> /// <returns></returns> public Bitmap CopyToBitmap(int band, int width, int height, int startx, int starty, int readw, int readh) { Bitmap b = new Bitmap(width, height); var imgband = RasterImg.GetRasterBand(band); var colortable = imgband.GetColorTable(); byte[] bytes = new byte[readw * readh]; var getdatares = imgband.ReadRaster(startx, starty, readw, readh, bytes, readw, readh, 0, 0); for (int x = 0; x < readw; x++) { for (int y = 0; y < readh; y++) { var index = bytes[y * readw + x]; var col = colortable.GetColorEntry(index); var c = Color.FromArgb(col.c4, col.c1, col.c2, col.c3); b.SetPixel(x, y, c); } } return(b); }
public void Save(int xoff, int yoff, int buf_xsize, int buf_ysize, double[] buffer) { try { OSGeo.GDAL.Gdal.AllRegister(); _dataSet = OSGeo.GDAL.Gdal.Open(_fileName, OSGeo.GDAL.Access.GA_Update); _band1 = _dataSet.GetRasterBand(1); CPLErr err1 = _band1.WriteRaster(xoff, yoff, _resultInfo.Width, buf_ysize, buffer, buf_xsize, buf_ysize, 0, 0); _dataSet.Dispose(); _band1.Dispose(); } catch (Exception ex) { throw new Exception("数据写入失败。" + ex.Message); } }
public GDAL_Info(Dataset ds) { Projection = ds.GetProjectionRef(); Resolution = new Size(ds.RasterXSize, ds.RasterYSize); Bands = new DataBandInfo[ds.RasterCount]; for (int i = 0; i < ds.RasterCount; i++) { Band band = ds.GetRasterBand(i + 1); Bands[i] = new DataBandInfo(); int temp; band.GetMaximum(out Bands[i].MaxValue, out temp); band.GetMaximum(out Bands[i].MinValue, out temp); band.GetNoDataValue(out Bands[i].NODATAValue, out temp); ColorInterp clr = band.GetRasterColorInterpretation(); switch (clr) { case ColorInterp.GCI_RedBand: Bands[i].Name = "RedBand"; Bands[i].Image = Resource1.red_layer; BppType += "R"; break; case ColorInterp.GCI_GreenBand: Bands[i].Name = "GreenBand"; Bands[i].Image = Resource1.green_layer; BppType += "G"; break; case ColorInterp.GCI_BlueBand: Bands[i].Name = "BlueBand"; Bands[i].Image = Resource1.blue_layer; BppType += "B"; break; default: Bands[i].Name = clr.ToString(); Bands[i].Image = null; BppType += "?"; break; } BppType += "[" + Gdal.GetDataTypeName(band.DataType) + "]"; Bpp += (ushort)Gdal.GetDataTypeSize(band.DataType); if (i + 1 < ds.RasterCount) BppType += ","; } BppType += " (" + Bpp + ")"; Driver = ds.GetDriver().LongName; Metadata = ds.GetMetadata(""); ImgMetadata = ds.GetMetadata("IMAGE_STRUCTURE"); SubDSMetadata = ds.GetMetadata("SUBDATASETS"); GeoLocMetadata = ds.GetMetadata("GEOLOCATION"); GDALInfoGetPosition(ds, 0.0, 0.0, out UpperLeftX, out UpperLeftY); GDALInfoGetPosition(ds, 0.0, ds.RasterYSize, out UpperRightX, out UpperRightY); GDALInfoGetPosition(ds, ds.RasterXSize, 0.0, out LowerLeftX, out LowerLeftY); GDALInfoGetPosition(ds, ds.RasterXSize, ds.RasterYSize, out LowerRightX, out LowerRightY); GDALInfoGetPosition(ds, ds.RasterXSize / 2, ds.RasterYSize / 2, out CenterX, out CenterY); }
public GDALTerrainTileService(OSGeo.GDAL.Dataset dataset, string datasetName, double lztsd, int nlevels, string tiledir) : base(null, datasetName, lztsd, 256, ".bil", nlevels, tiledir, new TimeSpan(), "") { m_dataset = dataset; m_lines = dataset.RasterYSize; m_pixels = dataset.RasterXSize; dataset.GetGeoTransform(m_transform); if (dataset.GetRasterBand(1).DataType == (DataType)OSGeo.GDAL.GdalConst.GDT_Int16) { this.m_dataType = "Int16"; } else if (dataset.GetRasterBand(1).DataType == (DataType)OSGeo.GDAL.GdalConst.GDT_Float32) { this.m_dataType = "Float32"; } }
/// <summary> /// 和GetData功能相同,但是使用GDAL直接从文件中读取数据。 /// </summary> /// <param name="fileName">文件名字</param> /// <param name="width">ref用于返回数据的宽度</param> /// <param name="height">ref用于返回数据的高度</param> /// <returns>一维数据数组,按行优先</returns> private double[] GdalGetData(string fileName, ref int width, ref int height) { OSGeo.GDAL.Dataset dataset = OSGeo.GDAL.Gdal.Open(fileName, OSGeo.GDAL.Access.GA_ReadOnly); width = dataset.RasterXSize; height = dataset.RasterYSize; double[] imageBuffer = new double[width * height]; OSGeo.GDAL.Band b = dataset.GetRasterBand(1); b.ReadRaster(0, 0, width, height, imageBuffer, width, height, 0, 0); return(imageBuffer); }
/// <summary> /// /// </summary> /// <param name="filename"></param> /// <param name="ds"></param> /// <param name="band"></param> internal GdalImage(string filename, Dataset ds, ImageBandType band) { _dataset = ds; if (band == ImageBandType.ARGB) { using (Band bnd = ds.GetRasterBand(1)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_AlphaBand); } using (Band bnd = ds.GetRasterBand(2)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_RedBand); } using (Band bnd = ds.GetRasterBand(3)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_GreenBand); } using (Band bnd = ds.GetRasterBand(4)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_BlueBand); } } else if (band == ImageBandType.RGB) { using (Band bnd = ds.GetRasterBand(1)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_RedBand); } using (Band bnd = ds.GetRasterBand(2)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_GreenBand); } using (Band bnd = ds.GetRasterBand(3)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_BlueBand); } } else if (band == ImageBandType.PalletCoded) { using (Band bnd = ds.GetRasterBand(3)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_PaletteIndex); } } else { using (Band bnd = ds.GetRasterBand(3)) { bnd.SetRasterColorInterpretation(ColorInterp.GCI_GrayIndex); } } Filename = filename; WorldFile = new WorldFile { Affine = new double[6] }; Gdal.AllRegister(); }
///// <summary> ///// 根据栅格图层名字返回栅格图层数据数组 ///// </summary> ///// <param name="layerName">图层名字</param> ///// <param name="width">ref类型,数据的宽度</param> ///// <param name="height">ref类型,数据的高度</param> ///// <returns>数据数组,按行优先</returns> //private double[] GetData(string layerName, ref int width, ref int height) //{ // var map = GIS.FrameWork.Application.App.Map; // var layers = map.Layers; // ILayer selectedLayer = null; // for (int i = 0; i < layers.Count; i++) // { // var layer = layers[i]; // if (layer.LegendText == layerName) // { // selectedLayer = layer; // break; // } // } // if (selectedLayer == null) // { // return null; // 图层名无效 // } // try // { // RasterLayer rasterLayer = selectedLayer as RasterLayer; // IRaster rasterDataSet = rasterLayer.DataSet; // Dataset dataset = GIS.GDAL.RasterConverter.Ds2GdalRaster(rasterDataSet, null, new int[] { 1 }); // width = dataset.RasterXSize; // height = dataset.RasterYSize; // double[] imageBuffer = new double[width * height]; // Band band = dataset.GetRasterBand(1); // band.ReadRaster(0, 0, width, height, imageBuffer, width, height, 0, 0); // return imageBuffer; // } // catch // { // return null; // 图层不是栅格图层或将图层转化为GDAL dataset失败或从GDAL dataset中读取数据失败 // } //} /// <summary> /// 和GetData功能相同,但是使用GDAL直接从文件中读取数据。 /// 获取空间参照信息 /// </summary> /// <param name="fileName">文件名字</param> /// <param name="width">ref用于返回数据的宽度</param> /// <param name="height">ref用于返回数据的高度</param> /// <returns>一维数据数组,按行优先</returns> protected double[] GdalGetData(string fileName, ref int width, ref int height) { OSGeo.GDAL.Dataset dataset = OSGeo.GDAL.Gdal.Open(fileName, OSGeo.GDAL.Access.GA_ReadOnly); width = dataset.RasterXSize; height = dataset.RasterYSize; this.geoTransform = new double[6]; dataset.GetGeoTransform(geoTransform); this.projStr = dataset.GetProjection(); this.tiffType = dataset.GetType(); double[] imageBuffer = new double[width * height]; OSGeo.GDAL.Band b = dataset.GetRasterBand(1); b.ReadRaster(0, 0, width, height, imageBuffer, width, height, 0, 0); double noDataVal; int hasVal; b.GetNoDataValue(out noDataVal, out hasVal); this.noDataVal = noDataVal; return(imageBuffer); }
private static void SaveBitmapPaletteDirect(Dataset ds, string filename, int iOverview) { // Get the GDAL Band objects from the Dataset Band band = ds.GetRasterBand(1); if (iOverview >= 0 && band.GetOverviewCount() > iOverview) band = band.GetOverview(iOverview); ColorTable ct = band.GetRasterColorTable(); if (ct == null) { Console.WriteLine(" Band has no color table!"); return; } if (ct.GetPaletteInterpretation() != PaletteInterp.GPI_RGB) { Console.WriteLine(" Only RGB palette interp is supported by this sample!"); return; } // Get the width and height of the Dataset int width = band.XSize; int height = band.YSize; // Create a Bitmap to store the GDAL image in Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed); DateTime start = DateTime.Now; byte[] r = new byte[width * height]; band.ReadRaster(0, 0, width, height, r, width, height, 0, 0); // Use GDAL raster reading methods to read the image data directly into the Bitmap BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); try { int iCol = ct.GetCount(); ColorPalette pal = bitmap.Palette; for (int i = 0; i < iCol; i++) { ColorEntry ce = ct.GetColorEntry(i); pal.Entries[i] = Color.FromArgb(ce.c4, ce.c1, ce.c2, ce.c3); } bitmap.Palette = pal; int stride = bitmapData.Stride; IntPtr buf = bitmapData.Scan0; band.ReadRaster(0, 0, width, height, buf, width, height, DataType.GDT_Byte, 1, stride); TimeSpan renderTime = DateTime.Now - start; Console.WriteLine("SaveBitmapDirect fetch time: " + renderTime.TotalMilliseconds + " ms"); } finally { bitmap.UnlockBits(bitmapData); } bitmap.Save(filename); }
/// <summary> /// Attempts to open the specified file. /// </summary> public override void Open() { _dataset = Helpers.Open(Filename); _red = _dataset.GetRasterBand(1); if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex) { ReadPaletteBuffered(); } if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) { ReadGrayIndex(); } if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) { ReadRgb(); } if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_AlphaBand) { ReadArgb(); } }
private static void ReadRasterBlocks(ref Dataset valueRaster, ref Dataset zoneRaster) { _rasInfoDict = new Dictionary<int, StatisticsInfo>[valueRaster.RasterCount]; int valueRasterBandCount = valueRaster.RasterCount; int rasterRows = zoneRaster.RasterYSize; int rasterCols = zoneRaster.RasterXSize; const int blockSize = AppUtils.GdalUtilConstants.RasterBlockSize; for (int rasBand = 0; rasBand < valueRasterBandCount; rasBand++) { Band bandValueRaster = valueRaster.GetRasterBand(rasBand + 1); Band bandZoneRaster = zoneRaster.GetRasterBand(1); _rasInfoDict[rasBand] = new Dictionary<int, StatisticsInfo>(); for (int row = 0; row < rasterRows; row += blockSize) { int rowProcess; if (row + blockSize < rasterRows) { rowProcess = blockSize; } else { rowProcess = rasterRows - row; } for (int col = 0; col < rasterCols; col += blockSize) { int colProcess; if (col + blockSize < rasterCols) { colProcess = blockSize; } else { colProcess = rasterCols - col; } double[] valueRasterValues = new double[rowProcess * colProcess]; double[] zoneRasterValues = new double[rowProcess * colProcess]; bandValueRaster.ReadRaster(col, row, colProcess, rowProcess, valueRasterValues, colProcess, rowProcess, 0, 0); bandZoneRaster.ReadRaster(col, row, colProcess, rowProcess, zoneRasterValues, colProcess, rowProcess, 0, 0); ProcessEachRasterBlock(valueRasterValues, zoneRasterValues, rasBand, ref _rasInfoDict); } } } //flush rasters cache valueRaster.FlushCache(); zoneRaster.FlushCache(); valueRaster.Dispose(); zoneRaster.Dispose(); StatisticsExport writer = new StatisticsExport(_zoneFile); writer.ExportZonalStatistics(ref _rasInfoDict, _cellSize); }
/// <summary> /// RGB转灰度显示。 /// </summary> /// <param name="InputImg">影像对象。</param> /// <param name="RGBWeight">RGB权重数组,长度为3。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool RGB2GrayScale(Img InputImg, double[] RGBWeight, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (OutPath == InputImg.Path) { throw new Exception("输出路径与源文件相同。"); } if (InputImg.GDALDataset == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if (RGBWeight.Length != 3) { throw new ArgumentException("权重数组长度无效,应为3。"); } if (Math.Abs(RGBWeight[0] + RGBWeight[1] + RGBWeight[2] - 1) > 1E-7) { throw new ArgumentOutOfRangeException("RGB分量权重设置错误。总和应为1。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputImg.Width; int ySize = InputImg.Height; FrmProgress FP = new FrmProgress() { Text = "正在导出灰度影像...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputImg.GDALDataset, DS); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理", Row + 1, ySize, "行"); double[] RValues = new double[xSize]; double[] GValues = new double[xSize]; double[] BValues = new double[xSize]; double[] GrayValues = new double[xSize]; InputImg.GDALDataset.GetRasterBand(InputImg.BandList[0]).ReadRaster(0, Row, xSize, 1, RValues, xSize, 1, 0, 0); InputImg.GDALDataset.GetRasterBand(InputImg.BandList[1]).ReadRaster(0, Row, xSize, 1, GValues, xSize, 1, 0, 0); InputImg.GDALDataset.GetRasterBand(InputImg.BandList[2]).ReadRaster(0, Row, xSize, 1, BValues, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //拉伸到0~255后再加权计算。 RValues[Col] = LinearStretch(RValues[Col], InputImg.Min[InputImg.BandList[0] - 1], InputImg.Max[InputImg.BandList[0] - 1]); GValues[Col] = LinearStretch(GValues[Col], InputImg.Min[InputImg.BandList[1] - 1], InputImg.Max[InputImg.BandList[1] - 1]); BValues[Col] = LinearStretch(BValues[Col], InputImg.Min[InputImg.BandList[2] - 1], InputImg.Max[InputImg.BandList[2] - 1]); GrayValues[Col] = RGBWeight[0] * RValues[Col] + RGBWeight[1] * GValues[Col] + RGBWeight[2] * BValues[Col]; } //写结果到新栅格 DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, GrayValues, xSize, 1, 0, 0); DS.FlushCache(); } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.Message); return(false); } }
private void GetNonRotatedPreview(Dataset dataset, Size size, Graphics g, Envelope bbox, ProjectionInfo mapProjection) #endif { double[] geoTrans = new double[6]; dataset.GetGeoTransform(geoTrans); // default transform if (!_useRotation && !HaveSpot || (geoTrans[0] == 0 && geoTrans[3] == 0)) geoTrans = new[] { 999.5, 1, 0, 1000.5, 0, -1 }; Bitmap bitmap = null; var geoTransform = new GeoTransform(geoTrans); int DsWidth = 0; int DsHeight = 0; BitmapData bitmapData = null; double[] intVal = new double[Bands]; int p_indx; double bitScalar = 1.0; double dblImginMapW = 0, dblImginMapH = 0, dblLocX = 0, dblLocY = 0; int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((bbox.MinX > _envelope.MaxX) || (bbox.MaxX < _envelope.MinX) || (bbox.MaxY < _envelope.MinY) || (bbox.MinY > _envelope.MaxY)) return; DsWidth = _imageSize.Width; DsHeight = _imageSize.Height; Histogram = new List<int[]>(); for (int i = 0; i < Bands + 1; i++) Histogram.Add(new int[256]); double left = Math.Max(bbox.MinX, _envelope.MinX); double top = Math.Min(bbox.MaxY, _envelope.MaxY); double right = Math.Min(bbox.MaxX, _envelope.MaxX); double bottom = Math.Max(bbox.MinY, _envelope.MinY); double x1 = Math.Abs(geoTransform.PixelX(left)); double y1 = Math.Abs(geoTransform.PixelY(top)); double imgPixWidth = geoTransform.PixelXwidth(right - left); double imgPixHeight = geoTransform.PixelYwidth(bottom - top); //get screen pixels image should fill double dblBBoxW = bbox.Width; double dblBBoxtoImgPixX = imgPixWidth / dblBBoxW; dblImginMapW = size.Width * dblBBoxtoImgPixX * geoTransform.HorizontalPixelResolution; double dblBBoxH = bbox.Height; double dblBBoxtoImgPixY = imgPixHeight / dblBBoxH; dblImginMapH = size.Height * dblBBoxtoImgPixY * -geoTransform.VerticalPixelResolution; if ((dblImginMapH == 0) || (dblImginMapW == 0)) return; // ratios of bounding box to image ground space double dblBBoxtoImgX = size.Width / dblBBoxW; double dblBBoxtoImgY = size.Height / dblBBoxH; // set where to display bitmap in Map if (bbox.MinX != left) { if (bbox.MaxX != right) dblLocX = (_envelope.MinX - bbox.MinX) * dblBBoxtoImgX; else dblLocX = size.Width - dblImginMapW; } if (bbox.MaxY != top) { if (bbox.MinY != bottom) dblLocY = (bbox.MaxY - _envelope.MaxY) * dblBBoxtoImgY; else dblLocY = size.Height - dblImginMapH; } bitScalar = GetBitScalar(); try { bitmap = new Bitmap((int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), PixelFormat.Format24bppRgb); bitmapData = bitmap.LockBits( new Rectangle(0, 0, (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH)), ImageLockMode.ReadWrite, bitmap.PixelFormat); byte cr = _noDataInitColor.R; byte cg = _noDataInitColor.G; byte cb = _noDataInitColor.B; // Double[] noDataValues = new Double[Bands]; Double[] scales = new Double[Bands]; ColorTable colorTable = null; unsafe { double[][] buffer = new double[Bands][]; Band[] band = new Band[Bands]; int[] ch = new int[Bands]; // get data from image for (int i = 0; i < Bands; i++) { buffer[i] = new double[(int)Math.Round(dblImginMapW) * (int)Math.Round(dblImginMapH)]; band[i] = dataset.GetRasterBand(i + 1); //get nodata value if present Int32 hasVal = 0; band[i].GetNoDataValue(out noDataValues[i], out hasVal); if (hasVal == 0) noDataValues[i] = Double.NaN; band[i].GetScale(out scales[i], out hasVal); if (hasVal == 0) scales[i] = 1.0; band[i].ReadRaster((int)Math.Round(x1), (int)Math.Round(y1), (int)Math.Round(imgPixWidth), (int)Math.Round(imgPixHeight), buffer[i], (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), 0, 0); switch (band[i].GetRasterColorInterpretation()) { case ColorInterp.GCI_BlueBand: ch[i] = 0; break; case ColorInterp.GCI_GreenBand: ch[i] = 1; break; case ColorInterp.GCI_RedBand: ch[i] = 2; break; case ColorInterp.GCI_Undefined: if (Bands > 1) ch[i] = 3; // infrared else { ch[i] = 4; if (_colorBlend == null) { Double dblMin, dblMax; band[i].GetMinimum(out dblMin, out hasVal); if (hasVal == 0) dblMin = Double.NaN; band[i].GetMaximum(out dblMax, out hasVal); if (hasVal == 0) dblMax = double.NaN; if (Double.IsNaN(dblMin) || Double.IsNaN(dblMax)) { double dblMean, dblStdDev; band[i].GetStatistics(0, 1, out dblMin, out dblMax, out dblMean, out dblStdDev); //double dblRange = dblMax - dblMin; //dblMin -= 0.1*dblRange; //dblMax += 0.1*dblRange; } Single[] minmax = new float[] { Convert.ToSingle(dblMin), 0.5f * Convert.ToSingle(dblMin + dblMax), Convert.ToSingle(dblMax) }; Color[] colors = new Color[] { Color.Blue, Color.Yellow, Color.Red }; _colorBlend = new ColorBlend(colors, minmax); } intVal = new Double[3]; } break; case ColorInterp.GCI_GrayIndex: ch[i] = 0; break; case ColorInterp.GCI_PaletteIndex: colorTable = band[i].GetRasterColorTable(); ch[i] = 5; intVal = new Double[3]; break; default: ch[i] = -1; break; } } if (BitDepth == 32) ch = new[] { 0, 1, 2 }; p_indx = 0; for (int y = 0; y < Math.Round(dblImginMapH); y++) { byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < Math.Round(dblImginMapW); x++, p_indx++) { for (int i = 0; i < Bands; i++) { intVal[i] = buffer[i][p_indx]/bitScalar; Double imageVal = intVal[i] = intVal[i]/bitScalar; if (ch[i] == 4) { if (imageVal != noDataValues[i]) { Color color = _colorBlend.GetColor(Convert.ToSingle(imageVal)); intVal[0] = color.B; intVal[1] = color.G; intVal[2] = color.R; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else if (ch[i] == 5 && colorTable != null) { if (imageVal != noDataValues[i]) { ColorEntry ce = colorTable.GetColorEntry(Convert.ToInt32(imageVal)); intVal[0] = ce.c3; intVal[1] = ce.c2; intVal[2] = ce.c1; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else { if (ColorCorrect) { intVal[i] = ApplyColorCorrection(intVal[i], 0, ch[i], 0, 0); if (Bands >= 3) Histogram[Bands][ (int) (intVal[2]*0.2126 + intVal[1]*0.7152 + intVal[0]*0.0722)]++; } } if (intVal[i] > 255) intVal[i] = 255; } WritePixel(x, intVal, iPixelSize, ch, row); } } } } catch { return; } finally { if (bitmapData != null) bitmap.UnlockBits(bitmapData); } } if (TransparentColor != Color.Empty) bitmap.MakeTransparent(TransparentColor); g.DrawImage(bitmap, new Point((int)Math.Round(dblLocX), (int)Math.Round(dblLocY))); }
/// <summary> /// Attempts to open the specified file into memory. /// </summary> public override void Open() { try { _dataset = Gdal.Open(Filename, Access.GA_Update); } catch { try { _dataset = Gdal.Open(Filename, Access.GA_ReadOnly); } catch (Exception ex) { throw new GdalException(ex.ToString()); } } int numBands = _dataset.RasterCount; _red = _dataset.GetRasterBand(1); this.BandType = ImageBandType.RGB; for (int i = 1; i <= numBands; i++) { Band tempBand = _dataset.GetRasterBand(i); if (tempBand.GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) { this.BandType = ImageBandType.Gray; _red = tempBand; } if (tempBand.GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex) { this.BandType = ImageBandType.PalletCoded; _red = tempBand; } if (tempBand.GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) { _red = tempBand; } if (tempBand.GetRasterColorInterpretation() == ColorInterp.GCI_AlphaBand) { _alpha = tempBand; this.BandType = ImageBandType.ARGB; } else if (tempBand.GetRasterColorInterpretation() == ColorInterp.GCI_BlueBand) { _blue = tempBand; } else if (tempBand.GetRasterColorInterpretation() == ColorInterp.GCI_GreenBand) { _green = tempBand; } } /* if (this.BandType == ImageBandType.PalletCoded) { ReadPaletteBuffered(); } else if (this.BandType == ImageBandType.Gray) { ReadGrayIndex(); } else if (this.BandType == ImageBandType.ARGB) { ReadArgb(); } else if (this.BandType == ImageBandType.RGB) { ReadRgb(); }*/ }
/// <summary> /// This should update the palette cached and in the file. /// </summary> /// <param name="value"></param> public override void SetColorPalette(IEnumerable<Color> value) { ColorPalette = value; _dataset = Gdal.Open(Filename, Access.GA_Update); ColorTable ct = new ColorTable(PaletteInterp.GPI_RGB); int index = 0; foreach (Color c in value) { ColorEntry ce = new ColorEntry(); ce.c4 = c.A; ce.c3 = c.B; ce.c2 = c.G; ce.c1 = c.R; ct.SetColorEntry(index, ce); index++; } using (Band first = _dataset.GetRasterBand(1)) { first.SetRasterColorTable(ct); } }
private static void SaveBitmapDirect(Dataset ds, string filename, int iOverview) { // Get the GDAL Band objects from the Dataset Band redBand = ds.GetRasterBand(1); if (redBand.GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex) { SaveBitmapPaletteDirect(ds, filename, iOverview); return; } if (redBand.GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) { SaveBitmapGrayDirect(ds, filename, iOverview); return; } if (ds.RasterCount < 3) { Console.WriteLine("The number of the raster bands is not enough to run this sample"); System.Environment.Exit(-1); } if (iOverview >= 0 && redBand.GetOverviewCount() > iOverview) redBand = redBand.GetOverview(iOverview); Band greenBand = ds.GetRasterBand(2); if (iOverview >= 0 && greenBand.GetOverviewCount() > iOverview) greenBand = greenBand.GetOverview(iOverview); Band blueBand = ds.GetRasterBand(3); if (iOverview >= 0 && blueBand.GetOverviewCount() > iOverview) blueBand = blueBand.GetOverview(iOverview); // Get the width and height of the Dataset 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; // Use GDAL raster reading methods to read the image data directly into the Bitmap BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); try { int stride = bitmapData.Stride; IntPtr buf = bitmapData.Scan0; blueBand.ReadRaster(0, 0, width, height, buf, width, height, DataType.GDT_Byte, 4, stride); greenBand.ReadRaster(0, 0, width, height, new IntPtr(buf.ToInt32()+1), width, height, DataType.GDT_Byte, 4, stride); redBand.ReadRaster(0, 0, width, height, new IntPtr(buf.ToInt32()+2), width, height, DataType.GDT_Byte, 4, stride); TimeSpan renderTime = DateTime.Now - start; Console.WriteLine("SaveBitmapDirect fetch time: " + renderTime.TotalMilliseconds + " ms"); } finally { bitmap.UnlockBits(bitmapData); } bitmap.Save(filename); }
public static void ConvertFeatureToRaster(Layer layer, out Dataset outputDataset, double rasterCellSize, string fieldName) { DriverUtils.RegisterGdalOgrDrivers(); Envelope envelope = new Envelope(); layer.GetExtent(envelope, 0); //Compute the out raster cell resolutions int x_res = Convert.ToInt32((envelope.MaxX - envelope.MinX) / rasterCellSize); int y_res = Convert.ToInt32((envelope.MaxY - envelope.MinY) / rasterCellSize); //Console.WriteLine("Extent: " + envelope.MaxX + " " + envelope.MinX + " " + envelope.MaxY + " " + envelope.MinY); //Console.WriteLine("X resolution: " + x_res); //Console.WriteLine("X resolution: " + y_res); //Create new tiff in disk string tempRaster = "tempZoneRaster.tif"; if (File.Exists(tempRaster)) { File.Delete(tempRaster); } OSGeo.GDAL.Driver outputDriver = Gdal.GetDriverByName("GTiff"); outputDataset = outputDriver.Create(tempRaster, x_res, y_res, 1, DataType.GDT_Int32, null); //Extrac srs from input feature string inputShapeSrs; SpatialReference spatialRefrence = layer.GetSpatialRef(); spatialRefrence.ExportToWkt(out inputShapeSrs); //Assign input feature srs to outpur raster outputDataset.SetProjection(inputShapeSrs); //Geotransform double[] argin = new double[] { envelope.MinX, rasterCellSize, 0, envelope.MaxY, 0, -rasterCellSize }; outputDataset.SetGeoTransform(argin); //Set no data Band band = outputDataset.GetRasterBand(1); //band.SetNoDataValue(GdalUtilConstants.NoDataValue); band.Fill(GdalUtilConstants.NoDataValue, 0.0); //Feature to raster rasterize layer options //No of bands (1) int[] bandlist = new int[] { 1 }; //Values to be burn on raster (10.0) double[] burnValues = new double[] { 10.0 }; //Dataset myDataset = Gdal.Open(outputRasterFile, Access.GA_Update); //additional options string[] rasterizeOptions; //rasterizeOptions = new string[] { "ALL_TOUCHED=TRUE", "ATTRIBUTE=" + fieldName }; //To set all touched pixels into raster pixel rasterizeOptions = new string[] { "ATTRIBUTE=" + fieldName }; //Rasterize layer //Gdal.RasterizeLayer(myDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, null, null, null); // To burn the given burn values instead of feature attributes //Gdal.RasterizeLayer(outputDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, rasterizeOptions, new Gdal.GDALProgressFuncDelegate(ProgressFunc), "Raster conversion"); Gdal.RasterizeLayer(outputDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, rasterizeOptions, null, null); }
// add image pixels to the map protected virtual void GetPreview(Dataset dataset, System.Drawing.Size size, System.Drawing.Graphics g, BoundingBox displayBbox, ICoordinateSystem mapProjection, Map map) { double[] geoTrans = new double[6]; _GdalDataset.GetGeoTransform(geoTrans); // not rotated, use faster display method if ((!_useRotation || (geoTrans[1] == 1 && geoTrans[2] == 0 && geoTrans[4] == 0 && Math.Abs(geoTrans[5]) == 1)) && !_haveSpot && _transform == null) { GetNonRotatedPreview(dataset, size, g, displayBbox, mapProjection); return; } // not rotated, but has spot...need default rotation else if ((geoTrans[0] == 0 && geoTrans[3] == 0) && _haveSpot) geoTrans = new double[] { 999.5, 1, 0, 1000.5, 0, -1 }; GT = new GeoTransform(geoTrans); double DsWidth = _imagesize.Width; double DsHeight = _imagesize.Height; double left, top, right, bottom; double GndX = 0, GndY = 0, ImgX = 0, ImgY = 0, PixX, PixY; double[] intVal = new double[Bands]; double imageVal = 0, SpotVal = 0; double bitScalar = 1.0; Bitmap bitmap = null; GdiPoint bitmapTL = new GdiPoint(), bitmapBR = new GdiPoint(); SMPoint imageTL = new SMPoint(), imageBR = new SMPoint(); BoundingBox shownImageBbox, trueImageBbox; int bitmapLength, bitmapHeight; int displayImageLength, displayImageHeight; int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((displayBbox.Left > _Envelope.Right) || (displayBbox.Right < _Envelope.Left) || (displayBbox.Top < _Envelope.Bottom) || (displayBbox.Bottom > _Envelope.Top)) return; // init histo _histogram = new List<int[]>(); for (int i = 0; i < _lbands + 1; i++) _histogram.Add(new int[256]); // bounds of section of image to be displayed left = Math.Max(displayBbox.Left, _Envelope.Left); top = Math.Min(displayBbox.Top, _Envelope.Top); right = Math.Min(displayBbox.Right, _Envelope.Right); bottom = Math.Max(displayBbox.Bottom, _Envelope.Bottom); trueImageBbox = new BoundingBox(left, bottom, right, top); // put display bounds into current projection if (_transform != null) shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, _transform.MathTransform.Inverse()); else shownImageBbox = trueImageBbox; // find min/max x and y pixels needed from image imageBR.X = (int)(Math.Max(GT.GroundToImage(shownImageBbox.TopLeft).X, Math.Max(GT.GroundToImage(shownImageBbox.TopRight).X, Math.Max(GT.GroundToImage(shownImageBbox.BottomLeft).X, GT.GroundToImage(shownImageBbox.BottomRight).X))) + 1); imageBR.Y = (int)(Math.Max(GT.GroundToImage(shownImageBbox.TopLeft).Y, Math.Max(GT.GroundToImage(shownImageBbox.TopRight).Y, Math.Max(GT.GroundToImage(shownImageBbox.BottomLeft).Y, GT.GroundToImage(shownImageBbox.BottomRight).Y))) + 1); imageTL.X = (int)Math.Min(GT.GroundToImage(shownImageBbox.TopLeft).X, Math.Min(GT.GroundToImage(shownImageBbox.TopRight).X, Math.Min(GT.GroundToImage(shownImageBbox.BottomLeft).X, GT.GroundToImage(shownImageBbox.BottomRight).X))); imageTL.Y = (int)Math.Min(GT.GroundToImage(shownImageBbox.TopLeft).Y, Math.Min(GT.GroundToImage(shownImageBbox.TopRight).Y, Math.Min(GT.GroundToImage(shownImageBbox.BottomLeft).Y, GT.GroundToImage(shownImageBbox.BottomRight).Y))); // stay within image if (imageBR.X > _imagesize.Width) imageBR.X = _imagesize.Width; if (imageBR.Y > _imagesize.Height) imageBR.Y = _imagesize.Height; if (imageTL.Y < 0) imageTL.Y = 0; if (imageTL.X < 0) imageTL.X = 0; displayImageLength = (int)(imageBR.X - imageTL.X); displayImageHeight = (int)(imageBR.Y - imageTL.Y); // find ground coordinates of image pixels SMPoint groundBR = GT.ImageToGround(imageBR); SMPoint groundTL = GT.ImageToGround(imageTL); // convert ground coordinates to map coordinates to figure out where to place the bitmap bitmapBR = new GdiPoint((int)map.WorldToImage(trueImageBbox.BottomRight).X + 1, (int)map.WorldToImage(trueImageBbox.BottomRight).Y + 1); bitmapTL = new GdiPoint((int)map.WorldToImage(trueImageBbox.TopLeft).X, (int)map.WorldToImage(trueImageBbox.TopLeft).Y); bitmapLength = bitmapBR.X - bitmapTL.X; bitmapHeight = bitmapBR.Y - bitmapTL.Y; // check to see if image is on its side if (bitmapLength > bitmapHeight && displayImageLength < displayImageHeight) { displayImageLength = bitmapHeight; displayImageHeight = bitmapLength; } else { displayImageLength = bitmapLength; displayImageHeight = bitmapHeight; } // scale if (_bitDepth == 12) bitScalar = 16.0; else if (_bitDepth == 16) bitScalar = 256.0; else if (_bitDepth == 32) bitScalar = 16777216.0; // 0 pixels in length or height, nothing to display if (bitmapLength < 1 || bitmapHeight < 1) return; //initialize bitmap bitmap = new Bitmap(bitmapLength, bitmapHeight, PixelFormat.Format24bppRgb); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmapLength, bitmapHeight), ImageLockMode.ReadWrite, bitmap.PixelFormat); try { unsafe { // turn everything yellow, so we can make fill transparent for (int y = 0; y < bitmapHeight; y++) { byte* brow = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < bitmapLength; x++) { brow[x * 3 + 0] = 0; brow[x * 3 + 1] = 255; brow[x * 3 + 2] = 255; } } // create 3 dimensional buffer [band][x pixel][y pixel] double[][] tempBuffer = new double[Bands][]; double[][][] buffer = new double[Bands][][]; for (int i = 0; i < Bands; i++) { buffer[i] = new double[displayImageLength][]; for (int j = 0; j < displayImageLength; j++) buffer[i][j] = new double[displayImageHeight]; } Band[] band = new Band[Bands]; int[] ch = new int[Bands]; // get data from image for (int i = 0; i < Bands; i++) { tempBuffer[i] = new double[displayImageLength * displayImageHeight]; band[i] = dataset.GetRasterBand(i + 1); band[i].ReadRaster( (int)imageTL.X, (int)imageTL.Y, (int)(imageBR.X - imageTL.X), (int)(imageBR.Y - imageTL.Y), tempBuffer[i], displayImageLength, displayImageHeight, 0, 0); // parse temp buffer into the image x y value buffer long pos = 0; for (int y = 0; y < displayImageHeight; y++) { for (int x = 0; x < displayImageLength; x++, pos++) buffer[i][x][y] = tempBuffer[i][pos]; } if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_BlueBand) ch[i] = 0; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GreenBand) ch[i] = 1; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) ch[i] = 2; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_Undefined) ch[i] = 3; // infrared else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) ch[i] = 0; else ch[i] = -1; } // store these values to keep from having to make slow method calls int bitmapTLX = bitmapTL.X; int bitmapTLY = bitmapTL.Y; double imageTop = imageTL.Y; double imageLeft = imageTL.X; double dblMapPixelWidth = map.PixelWidth; double dblMapPixelHeight = map.PixelHeight; double dblMapMinX = map.Envelope.Min.X; double dblMapMaxY = map.Envelope.Max.Y; double geoTop, geoLeft, geoHorzPixRes, geoVertPixRes, geoXRot, geoYRot; // get inverse values geoTop = GT.Inverse[3]; geoLeft = GT.Inverse[0]; geoHorzPixRes = GT.Inverse[1]; geoVertPixRes = GT.Inverse[5]; geoXRot = GT.Inverse[2]; geoYRot = GT.Inverse[4]; double dblXScale = (imageBR.X - imageTL.X) / (displayImageLength - 1); double dblYScale = (imageBR.Y - imageTL.Y) / (displayImageHeight - 1); double[] dblPoint; // get inverse transform // NOTE: calling transform.MathTransform.Inverse() once and storing it // is much faster than having to call every time it is needed IMathTransform inverseTransform = null; if (_transform != null) inverseTransform = _transform.MathTransform.Inverse(); for (PixY = 0; PixY < bitmapBR.Y - bitmapTL.Y; PixY++) { byte* row = (byte*)bitmapData.Scan0 + ((int)Math.Round(PixY) * bitmapData.Stride); for (PixX = 0; PixX < bitmapBR.X - bitmapTL.X; PixX++) { // same as Map.ImageToGround(), but much faster using stored values...rather than called each time GndX = dblMapMinX + (PixX + (double)bitmapTLX) * dblMapPixelWidth; GndY = dblMapMaxY - (PixY + (double)bitmapTLY) * dblMapPixelHeight; // transform ground point if needed if (_transform != null) { dblPoint = inverseTransform.Transform(new double[] { GndX, GndY }); GndX = dblPoint[0]; GndY = dblPoint[1]; } // same as GeoTransform.GroundToImage(), but much faster using stored values... ImgX = (geoLeft + geoHorzPixRes * GndX + geoXRot * GndY); ImgY = (geoTop + geoYRot * GndX + geoVertPixRes * GndY); if (ImgX < imageTL.X || ImgX > imageBR.X || ImgY < imageTL.Y || ImgY > imageBR.Y) continue; // color correction for (int i = 0; i < Bands; i++) { intVal[i] = buffer[i][(int)((ImgX - imageLeft) / dblXScale)][(int)((ImgY - imageTop) / dblYScale)]; imageVal = SpotVal = intVal[i] = intVal[i] / bitScalar; if (_colorCorrect) { intVal[i] = ApplyColorCorrection(imageVal, SpotVal, ch[i], GndX, GndY); // if pixel is within ground boundary, add its value to the histogram if (ch[i] != -1 && intVal[i] > 0 && (_histoBounds.Bottom >= (int)GndY) && _histoBounds.Top <= (int)GndY && _histoBounds.Left <= (int)GndX && _histoBounds.Right >= (int)GndX) { _histogram[ch[i]][(int)intVal[i]]++; } } if (intVal[i] > 255) intVal[i] = 255; } // luminosity if (_lbands >= 3) _histogram[_lbands][(int)(intVal[2] * 0.2126 + intVal[1] * 0.7152 + intVal[0] * 0.0722)]++; WritePixel(PixX, intVal, iPixelSize, ch, row); } } } } finally { bitmap.UnlockBits(bitmapData); } } bitmap.MakeTransparent(Color.Yellow); if (_transparentColor != Color.Empty) bitmap.MakeTransparent(_transparentColor); g.DrawImage(bitmap, new System.Drawing.Point(bitmapTL.X, bitmapTL.Y)); }
protected virtual void GetPreview(Dataset dataset, Size size, Graphics g, BoundingBox displayBbox, ProjectionInfo mapProjection, Map map) #endif { double[] geoTrans = new double[6]; _gdalDataset.GetGeoTransform(geoTrans); // not rotated, use faster display method if ((!_useRotation || (geoTrans[1] == 1 && geoTrans[2] == 0 && geoTrans[4] == 0 && Math.Abs(geoTrans[5]) == 1)) && !_haveSpot && _transform == null) { GetNonRotatedPreview(dataset, size, g, displayBbox, mapProjection); return; } // not rotated, but has spot...need default rotation else if ((geoTrans[0] == 0 && geoTrans[3] == 0) && _haveSpot) geoTrans = new[] { 999.5, 1, 0, 1000.5, 0, -1 }; _geoTransform = new GeoTransform(geoTrans); double DsWidth = _imagesize.Width; double DsHeight = _imagesize.Height; double left, top, right, bottom; double GndX = 0, GndY = 0, ImgX = 0, ImgY = 0, PixX, PixY; double[] intVal = new double[Bands]; double imageVal = 0, SpotVal = 0; double bitScalar = 1.0; Bitmap bitmap = null; Point bitmapTL = new Point(), bitmapBR = new Point(); Geometries.Point imageTL = new Geometries.Point(), imageBR = new Geometries.Point(); BoundingBox shownImageBbox, trueImageBbox; int bitmapLength, bitmapHeight; int displayImageLength, displayImageHeight; int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((displayBbox.Left > _envelope.Right) || (displayBbox.Right < _envelope.Left) || (displayBbox.Top < _envelope.Bottom) || (displayBbox.Bottom > _envelope.Top)) return; // init histo _histogram = new List<int[]>(); for (int i = 0; i < _lbands + 1; i++) _histogram.Add(new int[256]); // bounds of section of image to be displayed left = Math.Max(displayBbox.Left, _envelope.Left); top = Math.Min(displayBbox.Top, _envelope.Top); right = Math.Min(displayBbox.Right, _envelope.Right); bottom = Math.Max(displayBbox.Bottom, _envelope.Bottom); trueImageBbox = new BoundingBox(left, bottom, right, top); // put display bounds into current projection if (_transform != null) { #if !DotSpatialProjections _transform.MathTransform.Invert(); shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, _transform.MathTransform); _transform.MathTransform.Invert(); #else shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, _transform.Source, _transform.Target); #endif } else shownImageBbox = trueImageBbox; // find min/max x and y pixels needed from image imageBR.X = (int) (Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopLeft).X, Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopRight).X, Math.Max(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).X, _geoTransform.GroundToImage(shownImageBbox.BottomRight).X))) + 1); imageBR.Y = (int) (Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopLeft).Y, Math.Max(_geoTransform.GroundToImage(shownImageBbox.TopRight).Y, Math.Max(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).Y, _geoTransform.GroundToImage(shownImageBbox.BottomRight).Y))) + 1); imageTL.X = (int) Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopLeft).X, Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopRight).X, Math.Min(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).X, _geoTransform.GroundToImage(shownImageBbox.BottomRight).X))); imageTL.Y = (int) Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopLeft).Y, Math.Min(_geoTransform.GroundToImage(shownImageBbox.TopRight).Y, Math.Min(_geoTransform.GroundToImage(shownImageBbox.BottomLeft).Y, _geoTransform.GroundToImage(shownImageBbox.BottomRight).Y))); // stay within image if (imageBR.X > _imagesize.Width) imageBR.X = _imagesize.Width; if (imageBR.Y > _imagesize.Height) imageBR.Y = _imagesize.Height; if (imageTL.Y < 0) imageTL.Y = 0; if (imageTL.X < 0) imageTL.X = 0; displayImageLength = (int)(imageBR.X - imageTL.X); displayImageHeight = (int)(imageBR.Y - imageTL.Y); // find ground coordinates of image pixels Geometries.Point groundBR = _geoTransform.ImageToGround(imageBR); Geometries.Point groundTL = _geoTransform.ImageToGround(imageTL); // convert ground coordinates to map coordinates to figure out where to place the bitmap bitmapBR = new Point((int)map.WorldToImage(trueImageBbox.BottomRight).X + 1, (int)map.WorldToImage(trueImageBbox.BottomRight).Y + 1); bitmapTL = new Point((int)map.WorldToImage(trueImageBbox.TopLeft).X, (int)map.WorldToImage(trueImageBbox.TopLeft).Y); bitmapLength = bitmapBR.X - bitmapTL.X; bitmapHeight = bitmapBR.Y - bitmapTL.Y; // check to see if image is on its side if (bitmapLength > bitmapHeight && displayImageLength < displayImageHeight) { displayImageLength = bitmapHeight; displayImageHeight = bitmapLength; } else { displayImageLength = bitmapLength; displayImageHeight = bitmapHeight; } // scale if (_bitDepth == 12) bitScalar = 16.0; else if (_bitDepth == 16) bitScalar = 256.0; else if (_bitDepth == 32) bitScalar = 16777216.0; // 0 pixels in length or height, nothing to display if (bitmapLength < 1 || bitmapHeight < 1) return; //initialize bitmap bitmap = new Bitmap(bitmapLength, bitmapHeight, PixelFormat.Format24bppRgb); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmapLength, bitmapHeight), ImageLockMode.ReadWrite, bitmap.PixelFormat); try { unsafe { // turn everything to _noDataInitColor, so we can make fill transparent byte cr = _noDataInitColor.R; byte cg = _noDataInitColor.G; byte cb = _noDataInitColor.B; for (int y = 0; y < bitmapHeight; y++) { byte* brow = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < bitmapLength; x++) { Int32 offsetX = x * 3; brow[offsetX++] = cb; brow[offsetX++] = cg; brow[offsetX] = cr; } } // create 3 dimensional buffer [band][x pixel][y pixel] double[][] tempBuffer = new double[Bands][]; double[][][] buffer = new double[Bands][][]; for (int i = 0; i < Bands; i++) { buffer[i] = new double[displayImageLength][]; for (int j = 0; j < displayImageLength; j++) buffer[i][j] = new double[displayImageHeight]; } Band[] band = new Band[Bands]; int[] ch = new int[Bands]; // Double[] noDataValues = new Double[Bands]; Double[] scales = new Double[Bands]; ColorTable colorTable = null; // get data from image for (int i = 0; i < Bands; i++) { tempBuffer[i] = new double[displayImageLength * displayImageHeight]; band[i] = dataset.GetRasterBand(i + 1); //get nodata value if present Int32 hasVal = 0; band[i].GetNoDataValue(out noDataValues[i], out hasVal); if (hasVal == 0) noDataValues[i] = Double.NaN; band[i].GetScale(out scales[i], out hasVal); if (hasVal == 0) scales[i] = 1.0; band[i].ReadRaster( (int)imageTL.X, (int)imageTL.Y, (int)(imageBR.X - imageTL.X), (int)(imageBR.Y - imageTL.Y), tempBuffer[i], displayImageLength, displayImageHeight, 0, 0); // parse temp buffer into the image x y value buffer long pos = 0; for (int y = 0; y < displayImageHeight; y++) { for (int x = 0; x < displayImageLength; x++, pos++) buffer[i][x][y] = tempBuffer[i][pos]; } if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_BlueBand) ch[i] = 0; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GreenBand) ch[i] = 1; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) ch[i] = 2; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_Undefined) { if (Bands > 1) ch[i] = 3; // infrared else { ch[i] = 4; if (_colorBlend == null) { Double dblMin, dblMax; band[i].GetMinimum(out dblMin, out hasVal); if (hasVal == 0) dblMin = Double.NaN; band[i].GetMaximum(out dblMax, out hasVal); if (hasVal == 0) dblMax = double.NaN; if (Double.IsNaN(dblMin) || Double.IsNaN(dblMax)) { double dblMean, dblStdDev; band[i].GetStatistics(0, 1, out dblMin, out dblMax, out dblMean, out dblStdDev); //double dblRange = dblMax - dblMin; //dblMin -= 0.1*dblRange; //dblMax += 0.1*dblRange; } Single[] minmax = new float[] { Convert.ToSingle(dblMin), 0.5f * Convert.ToSingle(dblMin + dblMax), Convert.ToSingle(dblMax) }; Color[] colors = new Color[] { Color.Blue, Color.Yellow, Color.Red }; _colorBlend = new ColorBlend(colors, minmax); } intVal = new Double[3]; } } else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) ch[i] = 0; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex) { colorTable = band[i].GetRasterColorTable(); ch[i] = 5; intVal = new Double[3]; } else ch[i] = -1; } // store these values to keep from having to make slow method calls int bitmapTLX = bitmapTL.X; int bitmapTLY = bitmapTL.Y; double imageTop = imageTL.Y; double imageLeft = imageTL.X; double dblMapPixelWidth = map.PixelWidth; double dblMapPixelHeight = map.PixelHeight; double dblMapMinX = map.Envelope.Min.X; double dblMapMaxY = map.Envelope.Max.Y; double geoTop, geoLeft, geoHorzPixRes, geoVertPixRes, geoXRot, geoYRot; // get inverse values geoTop = _geoTransform.Inverse[3]; geoLeft = _geoTransform.Inverse[0]; geoHorzPixRes = _geoTransform.Inverse[1]; geoVertPixRes = _geoTransform.Inverse[5]; geoXRot = _geoTransform.Inverse[2]; geoYRot = _geoTransform.Inverse[4]; double dblXScale = (imageBR.X - imageTL.X) / (displayImageLength - 1); double dblYScale = (imageBR.Y - imageTL.Y) / (displayImageHeight - 1); double[] dblPoint; // get inverse transform // NOTE: calling transform.MathTransform.Inverse() once and storing it // is much faster than having to call every time it is needed #if !DotSpatialProjections IMathTransform inverseTransform = null; if (_transform != null) inverseTransform = _transform.MathTransform.Inverse(); #endif for (PixY = 0; PixY < bitmapBR.Y - bitmapTL.Y; PixY++) { byte* row = (byte*)bitmapData.Scan0 + ((int)Math.Round(PixY) * bitmapData.Stride); for (PixX = 0; PixX < bitmapBR.X - bitmapTL.X; PixX++) { // same as Map.ImageToGround(), but much faster using stored values...rather than called each time GndX = dblMapMinX + (PixX + bitmapTLX) * dblMapPixelWidth; GndY = dblMapMaxY - (PixY + bitmapTLY) * dblMapPixelHeight; // transform ground point if needed if (_transform != null) { #if !DotSpatialProjections dblPoint = inverseTransform.Transform(new[] { GndX, GndY }); #else dblPoint = new double[] { GndX, GndY }; Reproject.ReprojectPoints(dblPoint, null, _transform.Source, _transform.Target, 0, 1); #endif GndX = dblPoint[0]; GndY = dblPoint[1]; } // same as GeoTransform.GroundToImage(), but much faster using stored values... ImgX = (geoLeft + geoHorzPixRes * GndX + geoXRot * GndY); ImgY = (geoTop + geoYRot * GndX + geoVertPixRes * GndY); if (ImgX < imageTL.X || ImgX > imageBR.X || ImgY < imageTL.Y || ImgY > imageBR.Y) continue; // color correction for (int i = 0; i < Bands; i++) { intVal[i] = buffer[i][(int)((ImgX - imageLeft) / dblXScale)][ (int)((ImgY - imageTop) / dblYScale)]; imageVal = SpotVal = intVal[i] = intVal[i] / bitScalar; if (ch[i] == 4) { if (imageVal != noDataValues[i]) { Color color = _colorBlend.GetColor(Convert.ToSingle(imageVal)); intVal[0] = color.B; intVal[1] = color.G; intVal[2] = color.R; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else if (ch[i] == 5 && colorTable != null) { if (imageVal != noDataValues[i]) { ColorEntry ce = colorTable.GetColorEntry(Convert.ToInt32(imageVal)); intVal[0] = ce.c3; intVal[1] = ce.c2; intVal[2] = ce.c1; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else { if (_colorCorrect) { intVal[i] = ApplyColorCorrection(imageVal, SpotVal, ch[i], GndX, GndY); // if pixel is within ground boundary, add its value to the histogram if (ch[i] != -1 && intVal[i] > 0 && (_histoBounds.Bottom >= (int)GndY) && _histoBounds.Top <= (int)GndY && _histoBounds.Left <= (int)GndX && _histoBounds.Right >= (int)GndX) { _histogram[ch[i]][(int)intVal[i]]++; } } if (intVal[i] > 255) intVal[i] = 255; } } // luminosity if (_lbands >= 3) _histogram[_lbands][(int)(intVal[2] * 0.2126 + intVal[1] * 0.7152 + intVal[0] * 0.0722)] ++; WritePixel(PixX, intVal, iPixelSize, ch, row); } } } } finally { bitmap.UnlockBits(bitmapData); } } bitmap.MakeTransparent(_noDataInitColor); if (_transparentColor != Color.Empty) bitmap.MakeTransparent(_transparentColor); g.DrawImage(bitmap, new Point(bitmapTL.X, bitmapTL.Y)); }
// faster than rotated display private void GetNonRotatedPreview(Dataset dataset, Size size, Graphics g, BoundingBox bbox, ICoordinateSystem mapProjection) { double[] geoTrans = new double[6]; dataset.GetGeoTransform(geoTrans); // default transform if (!_useRotation && !_haveSpot || (geoTrans[0] == 0 && geoTrans[3] == 0)) geoTrans = new double[] { 999.5, 1, 0, 1000.5, 0, -1 }; Bitmap bitmap = null; GT = new GeoTransform(geoTrans); int DsWidth = 0; int DsHeight = 0; BitmapData bitmapData = null; double[] intVal = new double[Bands]; int p_indx; double bitScalar = 1.0; double dblImginMapW = 0, dblImginMapH = 0, dblLocX = 0, dblLocY = 0; int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((bbox.Left > _Envelope.Right) || (bbox.Right < _Envelope.Left) || (bbox.Top < _Envelope.Bottom) || (bbox.Bottom > _Envelope.Top)) return; DsWidth = _imagesize.Width; DsHeight = _imagesize.Height; _histogram = new List<int[]>(); for (int i = 0; i < _lbands + 1; i++) _histogram.Add(new int[256]); double left = Math.Max(bbox.Left, _Envelope.Left); double top = Math.Min(bbox.Top, _Envelope.Top); double right = Math.Min(bbox.Right, _Envelope.Right); double bottom = Math.Max(bbox.Bottom, _Envelope.Bottom); double x1 = Math.Abs(GT.PixelX(left)); double y1 = Math.Abs(GT.PixelY(top)); double imgPixWidth = GT.PixelXwidth(right - left); double imgPixHeight = GT.PixelYwidth(bottom - top); //get screen pixels image should fill double dblBBoxW = bbox.Right - bbox.Left; double dblBBoxtoImgPixX = (double)imgPixWidth / (double)dblBBoxW; dblImginMapW = (double)size.Width * dblBBoxtoImgPixX * GT.HorizontalPixelResolution; double dblBBoxH = bbox.Top - bbox.Bottom; double dblBBoxtoImgPixY = (double)imgPixHeight / (double)dblBBoxH; dblImginMapH = (double)size.Height * dblBBoxtoImgPixY * -GT.VerticalPixelResolution; if ((dblImginMapH == 0) || (dblImginMapW == 0)) return; // ratios of bounding box to image ground space double dblBBoxtoImgX = (double)size.Width / dblBBoxW; double dblBBoxtoImgY = (double)size.Height / dblBBoxH; // set where to display bitmap in Map if (bbox.Left != left) { if (bbox.Right != right) dblLocX = (_Envelope.Left - bbox.Left) * dblBBoxtoImgX; else dblLocX = (double)size.Width - dblImginMapW; } if (bbox.Top != top) { if (bbox.Bottom != bottom) dblLocY = (bbox.Top - _Envelope.Top) * dblBBoxtoImgY; else dblLocY = (double)size.Height - dblImginMapH; } // scale if (_bitDepth == 12) bitScalar = 16.0; else if (_bitDepth == 16) bitScalar = 256.0; else if (_bitDepth == 32) bitScalar = 16777216.0; try { bitmap = new Bitmap((int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), PixelFormat.Format24bppRgb); bitmapData = bitmap.LockBits(new Rectangle(0, 0, (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH)), ImageLockMode.ReadWrite, bitmap.PixelFormat); unsafe { double[][] buffer = new double[Bands][]; Band[] band = new Band[Bands]; int[] ch = new int[Bands]; // get data from image for (int i = 0; i < Bands; i++) { buffer[i] = new double[(int)Math.Round(dblImginMapW) * (int)Math.Round(dblImginMapH)]; band[i] = dataset.GetRasterBand(i + 1); band[i].ReadRaster((int)Math.Round(x1), (int)Math.Round(y1), (int)Math.Round(imgPixWidth), (int)Math.Round(imgPixHeight), buffer[i], (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), 0, 0); if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_BlueBand) ch[i] = 0; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GreenBand) ch[i] = 1; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) ch[i] = 2; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_Undefined) ch[i] = 3; // infrared else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) ch[i] = 4; else ch[i] = -1; } if (_bitDepth == 32) ch = new int[] { 0, 1, 2 }; p_indx = 0; for (int y = 0; y < Math.Round(dblImginMapH); y++) { byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < Math.Round(dblImginMapW); x++, p_indx++) { for (int i = 0; i < Bands; i++) { intVal[i] = buffer[i][p_indx] / bitScalar; if (_colorCorrect) { intVal[i] = ApplyColorCorrection(intVal[i], 0, ch[i], 0, 0); if (_lbands >= 3) _histogram[_lbands][(int)(intVal[2] * 0.2126 + intVal[1] * 0.7152 + intVal[0] * 0.0722)]++; } if (intVal[i] > 255) intVal[i] = 255; } WritePixel(x, intVal, iPixelSize, ch, row); } } } } catch { return; } finally { if (bitmapData != null) bitmap.UnlockBits(bitmapData); } } if (_transparentColor != Color.Empty) bitmap.MakeTransparent(_transparentColor); g.DrawImage(bitmap, new System.Drawing.Point((int)Math.Round(dblLocX), (int)Math.Round(dblLocY))); }
/// <summary> /// Brovey变换融合。融合前会将多光谱数据集的每一波段与全色数据集做直方图匹配。 /// </summary> /// <param name="PanDS">全色数据集。</param> /// <param name="MSDS">多光谱数据集</param> /// <param name="PanCumu">全色数据集的累积概率表。</param> /// <param name="MSCumu">多光谱数据集的累积概率表。</param> /// <param name="MSBandList">多光谱数据集的波段组合。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool Brovey(OSGeo.GDAL.Dataset PanDS, OSGeo.GDAL.Dataset MSDS, double[][] PanCumu, double[][] MSCumu, int[] MSBandList, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (PanDS == null) { throw new ArgumentNullException("输入的全色数据集为空。"); } if (PanDS.RasterCount > 1) { throw new RankException("全色数据集波段大于1。"); } if (MSDS == null) { throw new ArgumentNullException("输入的多光谱数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int panWidth = PanDS.RasterXSize; int panHeight = PanDS.RasterYSize; int msWidth = MSDS.RasterXSize; int msHeight = MSDS.RasterYSize; //int rat = (int)Math.Ceiling((double)panHeight / msHeight); if (panWidth < msWidth) { throw new RankException("全色数据集宽度小于多光谱数据集宽度。"); } if (panHeight < msHeight) { throw new RankException("全色数据集高度小于多光谱数据集高度。"); } //if (rat <= 0) // throw new ArgumentOutOfRangeException("全色高度:多光谱高度小于1。"); FrmProgress FP = new FrmProgress() { Text = "正在进行Brovey融合...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); #region 预处理 //创建临时文件,进行直方图匹配。 string HisMatFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset MatchingDS = Dri.CreateCopy(HisMatFileName, MSDS, 0, null, null, null); FP.Output("已创建直方图匹配临时文件\"" + HisMatFileName + "\""); for (int band = 1; band <= MSDS.RasterCount; band++) { FP.Output("正在进行直方图匹配(" + band.ToString() + "/" + MSDS.RasterCount.ToString() + ")..."); Band b = Tools.BaseProcess.HistogramMatching(MSDS.GetRasterBand(band), PanDS.GetRasterBand(1), MSCumu[band - 1], PanCumu[0], OutDataType); if (b == null) { throw new ArgumentNullException("直方图匹配返回波段为空。"); } for (int row = 0; row < b.YSize; row++) { double[] tmp = new double[b.XSize]; b.ReadRaster(0, row, b.XSize, 1, tmp, b.XSize, 1, 0, 0); MatchingDS.GetRasterBand(band).WriteRaster(0, row, MatchingDS.GetRasterBand(band).XSize, 1, tmp, MatchingDS.GetRasterBand(band).XSize, 1, 0, 0); MatchingDS.FlushCache(); Thread.Sleep(1); } } //创建临时文件,进行重采样。 double[] resamptmp; string ResampFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset ResampDS = Dri.Create(ResampFileName, panWidth, panHeight, 3, MSDS.GetRasterBand(1).DataType, null); FP.Output("已创建重采样临时文件\"" + ResampFileName + "\""); //Tools.Common.CopyMetadata(PanDS, tmpDS); //Gdal.ReprojectImage(MSDS, tmpDS, null, null, 0, 0, 0, null, null); //将直方图匹配后的图像重采样。 for (int i = 0; i < 3; i++) { FP.Output("正在对直方图匹配后影像进行重采样(" + (i + 1).ToString() + "/" + "3)..."); resamptmp = new double[panWidth * panHeight]; MatchingDS.GetRasterBand(MSBandList[i]).ReadRaster(0, 0, msWidth, msHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.GetRasterBand(i + 1).WriteRaster(0, 0, panWidth, panHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放直方图匹配图像资源。 MatchingDS.Dispose(); if (File.Exists(HisMatFileName)) { File.Delete(HisMatFileName); } FP.Output("已删除直方图匹配临时文件"); #endregion //创建输出数据集。 OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, panWidth, panHeight, 3, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(PanDS, DS); double[] p; double[][] ms; double[] ds; for (int row = 0; row < panHeight; row++) { FP.SetProgress2("正在处理", row + 1, panHeight, "行"); //将全色波段行读取进数组。 p = new double[panWidth]; PanDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, p, panWidth, 1, 0, 0); //将重采样后的多光谱行读取进数组。 ms = new double[3][]; ms[0] = new double[panWidth]; ms[1] = new double[panWidth]; ms[2] = new double[panWidth]; ResampDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, ms[0], panWidth, 1, 0, 0); ResampDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, ms[1], panWidth, 1, 0, 0); ResampDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, ms[2], panWidth, 1, 0, 0); //遍历三波段 for (int bandcount = 0; bandcount < 3; bandcount++) { FP.SetProgress1("正在处理", bandcount + 1, 3, "波段"); ds = new double[panWidth]; //临时数组 for (long i = 0; i < panWidth; i++) { ds[i] = p[i] * ms[bandcount][i] / (ms[0][i] + ms[1][i] + ms[2][i]); //Brovey公式 } DS.GetRasterBand(bandcount + 1).WriteRaster(0, row, panWidth, 1, ds, panWidth, 1, 0, 0); //计算完后的数据写入 DS.FlushCache(); } Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放重采样图像资源。 ResampDS.Dispose(); if (File.Exists(ResampFileName)) { File.Delete(ResampFileName); } FP.Output("已删除重采样临时文件"); /*一次性读取一时爽,遇到大文件爆内存。 * 一次性读取一时爽,遇到大文件爆内存。 * 一次性读取一时爽,遇到大文件爆内存。*/ //p = new double[panWidth * panHeight]; //ms = new double[3][]; //ms[0] = new double[panWidth * panHeight]; //ms[1] = new double[panWidth * panHeight]; //ms[2] = new double[panWidth * panHeight]; //PanDS.GetRasterBand(1).ReadRaster(0, 0, panWidth, panHeight, p, panWidth, panHeight, 0, 0); //MSDS.GetRasterBand(MSBandList[0]).ReadRaster(0, 0, msWidth, msHeight, ms[0], panWidth, panHeight, 0, 0); //MSDS.GetRasterBand(MSBandList[1]).ReadRaster(0, 0, msWidth, msHeight, ms[1], panWidth, panHeight, 0, 0); //MSDS.GetRasterBand(MSBandList[2]).ReadRaster(0, 0, msWidth, msHeight, ms[2], panWidth, panHeight, 0, 0); //for (int bandcount = 0; bandcount < 3; bandcount++) //{ // ds = new double[panWidth * panHeight]; // for (int row = 0; row < panHeight; row++) // { // for (int col = 0; col < panWidth; col++) // { // ds[row * panWidth + col] = p[row * panWidth + col] * ms[bandcount][row * panWidth + col] / (ms[0][row * panWidth + col] + ms[1][row * panWidth + col] + ms[2][row * panWidth + col]); // } // } // DS.GetRasterBand(bandcount + 1).WriteRaster(0, 0, panWidth, panHeight, ds, panWidth, panHeight, 0, 0); // DS.FlushCache(); //} FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// IHS融合。融合前会将全色数据集与多光谱数据集转换到IHS空间下的I波段做直方图匹配。 /// </summary> /// <param name="PanDS">全色数据集。</param> /// <param name="MSDS">多光谱数据集</param> /// <param name="PanCumu">全色数据集的累积概率表。</param> /// <param name="MSCumu">多光谱数据集的累积概率表。</param> /// <param name="MSBandList">多光谱数据集的波段组合。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool IHSFusion(OSGeo.GDAL.Dataset PanDS, OSGeo.GDAL.Dataset MSDS, double[][] PanCumu, double[][] MSCumu, int[] MSBandList, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (PanDS == null) { throw new ArgumentNullException("输入的全色数据集为空。"); } if (PanDS.RasterCount > 1) { throw new RankException("全色数据集波段大于1。"); } if (MSDS == null) { throw new ArgumentNullException("输入的多光谱数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int panWidth = PanDS.RasterXSize; int panHeight = PanDS.RasterYSize; int msWidth = MSDS.RasterXSize; int msHeight = MSDS.RasterYSize; if (panWidth < msWidth) { throw new RankException("全色数据集宽度小于多光谱数据集宽度。"); } if (panHeight < msHeight) { throw new RankException("全色数据集高度小于多光谱数据集高度。"); } FrmProgress FP = new FrmProgress() { Text = "正在进行IHS融合...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); #region 预处理 //创建临时文件,进行重采样。 double[] resamptmp; string ResampFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset ResampDS = Dri.Create(ResampFileName, panWidth, panHeight, MSDS.RasterCount, MSDS.GetRasterBand(1).DataType, null); FP.Output("已创建重采样临时文件\"" + ResampFileName + "\""); //将多光谱影像重采样。 for (int i = 0; i < 3; i++) { FP.Output("正在进行重采样(" + (i + 1).ToString() + "/" + "3)..."); resamptmp = new double[panWidth * panHeight]; MSDS.GetRasterBand(MSBandList[i]).ReadRaster(0, 0, msWidth, msHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.GetRasterBand(i + 1).WriteRaster(0, 0, panWidth, panHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } double[] BandMax = new double[3]; double[] BandMin = new double[3]; for (int i = 0; i < 3; i++) { FP.Output("正在计算重采样影像统计数据(" + (i + 1).ToString() + "/" + "3)..."); Common.ComputeRasterMinMax(ResampDS.GetRasterBand(i + 1), out BandMin[i], out BandMax[i]); } #endregion //多光谱RGB转IHS。 string MSIHSFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset MSIHSDS = Dri.Create(MSIHSFileName, panWidth, panHeight, 3, OSGeo.GDAL.DataType.GDT_Float32, null); FP.Output("已创建IHS临时文件\"" + MSIHSFileName + "\""); //按行读入,进行拉伸后再IHS转换,写入。 for (int row = 0; row < panHeight; row++) { FP.SetProgress1("正在处理IHS临时文件(", row + 1, panHeight, ")"); double[] iArr = new double[panWidth]; double[] hArr = new double[panWidth]; double[] sArr = new double[panWidth]; double[][] MSRGBArr = new double[3][]; MSRGBArr[0] = new double[panWidth]; MSRGBArr[1] = new double[panWidth]; MSRGBArr[2] = new double[panWidth]; //读。 ResampDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, MSRGBArr[0], panWidth, 1, 0, 0); ResampDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, MSRGBArr[1], panWidth, 1, 0, 0); ResampDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, MSRGBArr[2], panWidth, 1, 0, 0); //按行逐像元转IHS。 for (long i = 0; i < panWidth; i++) { double[] tmp = Common.RGB2IHS( new double[3] { Common.LinearStretchDouble(MSRGBArr[0][i], BandMin[0], BandMax[0]), Common.LinearStretchDouble(MSRGBArr[1][i], BandMin[1], BandMax[1]), Common.LinearStretchDouble(MSRGBArr[2][i], BandMin[2], BandMax[2]) }); iArr[i] = tmp[0]; hArr[i] = tmp[1]; sArr[i] = tmp[2]; } //写。 MSIHSDS.GetRasterBand(1).WriteRaster(0, row, panWidth, 1, iArr, panWidth, 1, 0, 0); MSIHSDS.GetRasterBand(2).WriteRaster(0, row, panWidth, 1, hArr, panWidth, 1, 0, 0); MSIHSDS.GetRasterBand(3).WriteRaster(0, row, panWidth, 1, sArr, panWidth, 1, 0, 0); MSIHSDS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放重采样数据集资源。 ResampDS.Dispose(); if (File.Exists(ResampFileName)) { File.Delete(ResampFileName); } FP.Output("已删除重采样临时文件"); //全色匹配多光谱I FP.Output("正在计算IHS统计数据..."); Common.GetStatistics(MSIHSDS.GetRasterBand(1), out double Imin, out double Imax, out double Imean, out double Istddev); //多光谱统计信息。 int[] IHis = new int[(int)(Imax - Imin) + 1]; MSIHSDS.GetRasterBand(1).GetHistogram(Imin, Imax, (int)(Imax - Imin) + 1, IHis, 1, 0, null, null); double[] ICumu = new double[IHis.Length]; for (int i = 0; i < IHis.Length; i++) { ICumu[i] = (double)IHis[i] / (MSIHSDS.RasterXSize * MSIHSDS.RasterYSize); if (i > 0) { ICumu[i] += ICumu[i - 1]; //累积概率 } } FP.Output("正在进行I波段直方图匹配..."); Band PanMatIBand = Tools.BaseProcess.HistogramMatching(PanDS.GetRasterBand(1), MSIHSDS.GetRasterBand(1), PanCumu[0], ICumu, OSGeo.GDAL.DataType.GDT_Float32); if (PanMatIBand == null) { throw new ArgumentNullException("直方图匹配返回波段为空。"); } //全色融合。 //创建输出数据集。 OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, panWidth, panHeight, 3, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(PanDS, DS); for (int row = 0; row < panHeight; row++) { FP.SetProgress1("正在融合(", row + 1, panHeight, ")"); //读取匹配多光谱I后的全色波段。 double[] Itmp = new double[panWidth]; PanMatIBand.ReadRaster(0, row, panWidth, 1, Itmp, panWidth, 1, 0, 0); //读入IHS变换后的多光谱影像的H、S波段。 double[] Htmp = new double[panWidth]; double[] Stmp = new double[panWidth]; MSIHSDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, Htmp, panWidth, 1, 0, 0); MSIHSDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, Stmp, panWidth, 1, 0, 0); double[] Rtmp = new double[panWidth]; double[] Gtmp = new double[panWidth]; double[] Btmp = new double[panWidth]; for (long i = 0; i < panWidth; i++) { double[] tmp = Common.IHS2RGB(new double[3] { Itmp[i], Htmp[i], Stmp[i] }); Rtmp[i] = tmp[0]; Gtmp[i] = tmp[1]; Btmp[i] = tmp[2]; } DS.GetRasterBand(1).WriteRaster(0, row, panWidth, 1, Rtmp, panWidth, 1, 0, 0); DS.GetRasterBand(2).WriteRaster(0, row, panWidth, 1, Gtmp, panWidth, 1, 0, 0); DS.GetRasterBand(3).WriteRaster(0, row, panWidth, 1, Btmp, panWidth, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放IHS图像资源。 MSIHSDS.Dispose(); PanMatIBand.Dispose(); if (File.Exists(MSIHSFileName)) { File.Delete(MSIHSFileName); } FP.Output("已删除IHS临时文件"); FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
private static void SaveBitmapPaletteBuffered(Dataset ds, string filename, int iOverview) { // Get the GDAL Band objects from the Dataset Band band = ds.GetRasterBand(1); if (iOverview >= 0 && band.GetOverviewCount() > iOverview) band = band.GetOverview(iOverview); ColorTable ct = band.GetRasterColorTable(); if (ct == null) { Console.WriteLine(" Band has no color table!"); return; } if (ct.GetPaletteInterpretation() != PaletteInterp.GPI_RGB) { Console.WriteLine(" Only RGB palette interp is supported by this sample!"); return; } // Get the width and height of the Dataset int width = band.XSize; int height = band.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]; band.ReadRaster(0, 0, width, height, r, 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++) { ColorEntry entry = ct.GetColorEntry(r[i+j*width]); Color newColor = Color.FromArgb(Convert.ToInt32(entry.c1),Convert.ToInt32(entry.c2), Convert.ToInt32(entry.c3)); bitmap.SetPixel(i, j, newColor); } } bitmap.Save(filename); }
/// <summary> /// GDAL栅格转换为位图 /// </summary> /// <param name="ds">GDAL Dataset</param> /// <param name="showRect">显示区域</param> /// <param name="bandlist">需要显示的波段列表</param> /// <returns>返回Bitmap对象</returns> public Bitmap GetImage(OSGeo.GDAL.Dataset ds, Rectangle showRect, int[] bandlist) { int imgWidth = ds.RasterXSize; //影像宽 int imgHeight = ds.RasterYSize; //影像高 float ImgRatio = imgWidth / (float)imgHeight; //影像宽高比 //获取显示控件大小 int BoxWidth = showRect.Width; int BoxHeight = showRect.Height; float BoxRatio = imgWidth / (float)imgHeight; //显示控件宽高比 //计算实际显示区域大小,防止影像畸变显示 int BufferWidth, BufferHeight; if (BoxRatio >= ImgRatio) { BufferHeight = BoxHeight; BufferWidth = (int)(BoxHeight * ImgRatio); } else { BufferWidth = BoxWidth; BufferHeight = (int)(BoxWidth / ImgRatio); } //构建位图 Bitmap bitmap = new Bitmap(BufferWidth, BufferHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb); if (bandlist.Length == 3) //RGB显示 { int[] r = new int[BufferWidth * BufferHeight]; Band band1 = ds.GetRasterBand(bandlist[0]); band1.ReadRaster(0, 0, imgWidth, imgHeight, r, BufferWidth, BufferHeight, 0, 0); //读取图像到内存 //为了显示好看,进行最大最小值拉伸显示 double[] maxandmin1 = { 0, 0 }; band1.ComputeRasterMinMax(maxandmin1, 0); int[] g = new int[BufferWidth * BufferHeight]; Band band2 = ds.GetRasterBand(bandlist[1]); band2.ReadRaster(0, 0, imgWidth, imgHeight, g, BufferWidth, BufferHeight, 0, 0); double[] maxandmin2 = { 0, 0 }; band2.ComputeRasterMinMax(maxandmin2, 0); int[] b = new int[BufferWidth * BufferHeight]; Band band3 = ds.GetRasterBand(bandlist[2]); band3.ReadRaster(0, 0, imgWidth, imgHeight, b, BufferWidth, BufferHeight, 0, 0); double[] maxandmin3 = { 0, 0 }; band3.ComputeRasterMinMax(maxandmin3, 0); int i, j; for (i = 0; i < BufferWidth; i++) { for (j = 0; j < BufferHeight; j++) { int rVal = Convert.ToInt32(r[i + j * BufferWidth]); rVal = (int)((rVal - maxandmin1[0]) / (maxandmin1[1] - maxandmin1[0]) * 255); int gVal = Convert.ToInt32(g[i + j * BufferWidth]); gVal = (int)((gVal - maxandmin2[0]) / (maxandmin2[1] - maxandmin2[0]) * 255); int bVal = Convert.ToInt32(b[i + j * BufferWidth]); bVal = (int)((bVal - maxandmin3[0]) / (maxandmin3[1] - maxandmin3[0]) * 255); Color newColor = Color.FromArgb(rVal, gVal, bVal); bitmap.SetPixel(i, j, newColor); } } } else //灰度显示 { int[] r = new int[BufferWidth * BufferHeight]; Band band1 = ds.GetRasterBand(bandlist[0]); band1.ReadRaster(0, 0, imgWidth, imgHeight, r, BufferWidth, BufferHeight, 0, 0); double[] maxandmin1 = { 0, 0 }; band1.ComputeRasterMinMax(maxandmin1, 0); int i, j; for (i = 0; i < BufferWidth; i++) { for (j = 0; j < BufferHeight; j++) { int rVal = Convert.ToInt32(r[i + j * BufferWidth]); rVal = (int)((rVal - maxandmin1[0]) / (maxandmin1[1] - maxandmin1[0]) * 255); Color newColor = Color.FromArgb(rVal, rVal, rVal); bitmap.SetPixel(i, j, newColor); } } } return(bitmap); }
private static Bitmap getBitmapRGBBandBuffered(Dataset ds) { Band redBand = ds.GetRasterBand(1); Band greenBand = ds.GetRasterBand(2); Band blueBand = ds.GetRasterBand(3); int width = redBand.XSize; int height = redBand.YSize; DateTime start = DateTime.Now; Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); 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); int i, j; for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { // r g b int rColor = Convert.ToInt32(r[i + j * width]); int gColor = Convert.ToInt32(g[i + j * width]); int bColor = Convert.ToInt32(b[i + j * width]); Color newColor = Color.FromArgb(rColor, gColor, bColor); bitmap.SetPixel(i, j, newColor); } } TimeSpan renderTime = DateTime.Now - start; double milliSeconds = renderTime.TotalMilliseconds; // ms //MessageBox.Show("GCI_RGB"); return bitmap; }
private Bitmap ReadRgb(int xOffset, int yOffset, int xSize, int ySize, Band first, Dataset set) { if (set.RasterCount < 3) { throw new GdalException( "RGB Format was indicated but there are only " + set.RasterCount + " bands!"); } Band first_o; Band green_o; Band blue_o; Band green = set.GetRasterBand(2); Band blue = set.GetRasterBand(3); int width = xSize; int height = ySize; if (first.GetOverviewCount() > 0 && _overview >= 0) { first_o = first.GetOverview(_overview); green_o = green.GetOverview(_overview); blue_o = blue.GetOverview(_overview); } else { first_o = first; green_o = green; blue_o = blue; } if (xOffset + width > first_o.XSize) { width = first_o.XSize - xOffset; } if (yOffset + height > first_o.YSize) { height = first_o.YSize - yOffset; } Bitmap result = new Bitmap(width, height, PixelFormat.Format32bppArgb); //byte[] r; if (r == null || r.Length != width * height) { r = new byte[width * height]; } if (g == null || g.Length != width * height) { g = new byte[width * height]; } if (b == null || b.Length != width * height) { b = new byte[width * height]; } if (vals == null || vals.Length != width * height * 4) { vals = new byte[width * height * 4]; } first_o.ReadRaster(xOffset, yOffset, width, height, r, width, height, 0, 0); green_o.ReadRaster(xOffset, yOffset, width, height, g, width, height, 0, 0); blue_o.ReadRaster(xOffset, yOffset, width, height, b, width, height, 0, 0); /* alternative way to call gdal unsafe { fixed (byte* p = r) { IntPtr ptr = (IntPtr)p; first_o.ReadRaster(xOffset, yOffset, width, height, ptr, width, height, DataType.GDT_Byte, 0, 0); } fixed (byte* p = g) { IntPtr ptr = (IntPtr)p; green_o.ReadRaster(xOffset, yOffset, width, height, ptr, width, height, DataType.GDT_Byte, 0, 0); } fixed (byte* p = b) { IntPtr ptr = (IntPtr)p; blue_o.ReadRaster(xOffset, yOffset, width, height, ptr, width, height, DataType.GDT_Byte, 0, 0); } }*/ //first disposed in caller green.Dispose(); blue.Dispose(); BitmapData bData = result.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int stride = Math.Abs(bData.Stride); for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { vals[row * stride + col * 4] = b[row * width + col]; vals[row * stride + col * 4 + 1] = g[row * width + col]; vals[row * stride + col * 4 + 2] = r[row * width + col]; vals[row * stride + col * 4 + 3] = 255; } } Marshal.Copy(vals, 0, bData.Scan0, vals.Length); result.UnlockBits(bData); //vals = null; //r = null; //g = null; //b = null; return result; }
/// <summary> /// This is only used in the palette indexed band type. /// </summary> public override IEnumerable<Color> GetColorPalette() { if (ColorPalette == null) { try { _dataset = Gdal.Open(Filename, Access.GA_Update); } catch { try { _dataset = Gdal.Open(Filename, Access.GA_ReadOnly); } catch (Exception ex) { throw new GdalException(ex.ToString()); } } Band first = _dataset.GetRasterBand(1); ColorTable ct = first.GetRasterColorTable(); int count = ct.GetCount(); List<Color> result = new List<Color>(); for (int i = 0; i < count; i++) { ColorEntry ce = ct.GetColorEntry(i); result.Add(Color.FromArgb(ce.c4, ce.c1, ce.c2, ce.c3)); } ColorPalette = result; } return ColorPalette; }
private Bitmap ReadArgb(int xOffset, int yOffset, int xSize, int ySize, Band first, Dataset set) { if (set.RasterCount < 4) { throw new GdalException( "ARGB Format was indicated but there are only " + set.RasterCount + " bands!"); } Band first_o; Band red_o; Band green_o; Band blue_o; Band red = set.GetRasterBand(2); Band green = set.GetRasterBand(3); Band blue = set.GetRasterBand(4); int width = xSize; int height = ySize; if (first.GetOverviewCount() > 0 && _overview >= 0) { first_o = first.GetOverview(_overview); red_o = red.GetOverview(_overview); green_o = green.GetOverview(_overview); blue_o = blue.GetOverview(_overview); } else { first_o = first; red_o = red; green_o = green; blue_o = blue; } if (xOffset + width > first_o.XSize) { width = first_o.XSize - xOffset; } if (yOffset + height > first_o.YSize) { height = first_o.YSize - yOffset; } Bitmap result = new Bitmap(width, height, PixelFormat.Format32bppArgb); byte[] a = new byte[width * height]; byte[] r = new byte[width * height]; byte[] g = new byte[width * height]; byte[] b = new byte[width * height]; first_o.ReadRaster(0, 0, width, height, a, width, height, 0, 0); red_o.ReadRaster(0, 0, width, height, r, width, height, 0, 0); green_o.ReadRaster(0, 0, width, height, g, width, height, 0, 0); blue_o.ReadRaster(0, 0, width, height, b, width, height, 0, 0); // Alpha disposed in caller red.Dispose(); green.Dispose(); blue.Dispose(); BitmapData bData = result.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int stride = Math.Abs(bData.Stride); byte[] vals = new byte[height * stride]; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { vals[row * stride + col * 4] = b[row * width + col]; vals[row * stride + col * 4 + 1] = g[row * width + col]; vals[row * stride + col * 4 + 2] = r[row * width + col]; vals[row * stride + col * 4 + 3] = a[row * width + col]; } } Marshal.Copy(vals, 0, bData.Scan0, vals.Length); result.UnlockBits(bData); return result; }
/// <summary> /// Opens the specified file /// </summary> /// <param name="filename"></param> /// <returns></returns> public IRaster Open(string filename) { IRaster result = null; try { _dataset = Gdal.Open(filename, Access.GA_Update); } catch { try { _dataset = Gdal.Open(filename, Access.GA_ReadOnly); } catch (Exception ex) { throw new GdalException(ex.ToString()); } } // Single band rasters are easy, just return the band as the raster. if(_dataset.RasterCount == 1) { result = GetBand(filename, _dataset.GetRasterBand(1)); } int c = Gdal.GetDriverCount(); string message = ""; for(int i = 0; i < c; i++) { Driver d = Gdal.GetDriver(i); message += i + ": " + d.LongName + ":" + d.ShortName + "; " + d.HelpTopic + "\n"; } System.Diagnostics.Debug.Write(message); // Otherwise, we need to make a more complicated raster structure with individual bands. return result; }
/// <summary> /// 导出当前视图。 /// </summary> /// <param name="InputImg">影像对象。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool ExportView(Img InputImg, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (OutPath == InputImg.Path) { throw new Exception("输出路径与源文件相同。"); } if (InputImg.GDALDataset == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputImg.Width; int ySize = InputImg.Height; int Bandnum = 3; if (InputImg.IsGrayscale) { Bandnum = 1; } else { Bandnum = 3; } FrmProgress FP = new FrmProgress() { Text = "正在导出影像...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, Bandnum, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputImg.GDALDataset, DS); for (int i = 0; i < Bandnum; i++) //遍历每个波段 { FP.SetProgress2("正在处理", i + 1, Bandnum, "波段"); for (int Row = 0; Row < ySize; Row++) //遍历每一行(y) { FP.SetProgress1("正在处理", Row + 1, ySize, "行"); double[] Values = new double[xSize]; //读取DN到数组 InputImg.GDALDataset.GetRasterBand(InputImg.BandList[i]).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) //对每一个值进行计算 { //无拉伸不做处理直接导出 if (InputImg.StretchMode == 0) { break; } //已经有处理的情形 switch (InputImg.StretchMode) { case 1: case 2: case 3: case 4: case 9: { //线性 Values[Col] = LinearStretch(Values[Col], InputImg.StretchInfo[InputImg.BandList[i] - 1].Item1, InputImg.StretchInfo[InputImg.BandList[i] - 1].Item2); break; } case 5: { //直方图均衡 Values[Col] = EqualizationStretch(Values[Col], InputImg.CumulativeProbability[InputImg.BandList[i] - 1], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]); break; } case 6: { //高斯 Values[Col] = GaussianStretch(Values[Col], InputImg.CumulativeProbability[InputImg.BandList[i] - 1], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Mean[InputImg.BandList[i] - 1], InputImg.Stddev[InputImg.BandList[i] - 1]); break; } case 7: { //平方根 Values[Col] = SquarerootStretch(Values[Col], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]); break; } case 8: { //对数 Values[Col] = LinearStretch(LogarithmicStretch(Values[Col], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]), InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]); break; } default: { //不是0-9还能是啥? throw new Exception("拉伸模式未知。"); } } } //写结果到新栅格 DS.GetRasterBand(i + 1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.Message); return(false); } }
private static void WriteRgb(Bitmap value, int xOffset, int yOffset, Band first, Dataset set) { if (set.RasterCount < 3) { throw new GdalException( "RGB Format was indicated but there are only " + set.RasterCount + " bands!"); } int width = value.Width; int height = value.Height; BitmapData bData = value.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int stride = Math.Abs(bData.Stride); byte[] vals = new byte[stride * height]; Marshal.Copy(bData.Scan0, vals, 0, vals.Length); value.UnlockBits(bData); byte[] r = new byte[width * height]; byte[] g = new byte[width * height]; byte[] b = new byte[width * height]; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { b[row * width + col] = vals[row * stride + col * 4]; g[row * width + col] = vals[row * stride + col * 4 + 1]; r[row * width + col] = vals[row * stride + col * 4 + 2]; } } Band green = set.GetRasterBand(2); Band blue = set.GetRasterBand(3); first.WriteRaster(xOffset, yOffset, width, height, r, width, height, 0, 0); first.FlushCache(); green.WriteRaster(xOffset, yOffset, width, height, g, width, height, 0, 0); green.FlushCache(); blue.WriteRaster(xOffset, yOffset, width, height, b, width, height, 0, 0); blue.FlushCache(); // first disposed in caller green.Dispose(); blue.Dispose(); }
/// <summary> /// 切分图像|| /// 解决图像过大导致的计算缓慢|| /// 输入图像路径,输出分幅路径|| /// 重叠区根据图像分辨率确定,约为实地100~200米 /// </summary> /// <param name="inPaht"></param> /// <returns></returns> public static List <string> getSubImg(string inPaht) { //注册插件 OSGeo.GDAL.Gdal.AllRegister(); OSGeo.GDAL.Driver gdalDriver = OSGeo.GDAL.Gdal.GetDriverByName("HFA"); //读进数据 OSGeo.GDAL.Dataset inDS = OSGeo.GDAL.Gdal.Open(inPaht, OSGeo.GDAL.Access.GA_ReadOnly); //根据栅格分辨率确定重叠区大小 double[] dsTraansform = new double[6]; inDS.GetGeoTransform(dsTraansform); if (dsTraansform[1] < 0.16) { xBuf = 1000; yBuf = 1000; } //1000*0.1=>100M if (dsTraansform[1] < 0.3) { xBuf = 500; yBuf = 500; } //500*0.25=>125M else if (dsTraansform[1] < 0.6) { xBuf = 300; yBuf = 300; } //300*0.5=>150M else if (dsTraansform[1] < 1.1) { xBuf = 200; yBuf = 150; } //150*1=>200M else if (dsTraansform[1] < 2.1) { xBuf = 100; yBuf = 100; } //100*2=>200M else { xBuf = 50; yBuf = 50; } //50*5=>250M //获取数据XY相元数量 int oriXcount = inDS.RasterXSize; int oriYcount = inDS.RasterYSize; //用来返回的文件路径列表 List <string> imgFilePaths = new List <string>(); if (oriXcount > userSetX || oriYcount > userSetY) { //确定文件行列数 int u, v; u = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(oriXcount) / userSetX)); //行文件数 v = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(oriYcount) / userSetY)); //列文件数 //循环列 for (int i = 0; i < v; i++) { //循环行 for (int j = 0; j < u; j++) { //////////// 定义起点 ///////////// int offX = j * userSetX; int offY = i * userSetY; //////////////定义边缘栅格大小///////////////// int thinkJ = userSetX * (j + 1) + xBuf; int thinkI = userSetY * (i + 1) + yBuf; int subXcount = oriXcount - thinkJ > 0 ? userSetX + xBuf : oriXcount - userSetX * j; int subYcount = oriYcount - thinkI > 0 ? userSetY + yBuf : oriYcount - userSetY * i; //////////// 把原栅格读进内存,内容为oriValue ///////////// OSGeo.GDAL.Band oriBand = inDS.GetRasterBand(1); double[] oriValue = new double[subXcount * subYcount]; oriBand.ReadRaster ( offX, //起点X索引 offY, //起点Y索引 subXcount, //X方向相元数量 subYcount, //Y方向相元数量 oriValue, //各相元值 subXcount, //执行读入的X方向数量 subYcount, //执行读入的Y方向数量 0, //执行读入的起点X索引 0 //执行读入的起点Y索引 ); //////////// 创建子栅格 ///////////// string imgFilePath = StaticTools.tempFilePath("img", i.ToString() + "_" + j.ToString()); OSGeo.GDAL.Dataset subDs = gdalDriver.Create ( imgFilePath, subXcount, subYcount, 1, OSGeo.GDAL.DataType.GDT_Float32, null ); subDs.SetProjection(inDS.GetProjectionRef()); //获取数据Transfrom double[] oriTransFrom = new double[6]; inDS.GetGeoTransform(oriTransFrom); oriTransFrom[0] = oriTransFrom[0] + offX * oriTransFrom[1] + offY * oriTransFrom[2]; oriTransFrom[3] = oriTransFrom[3] + offX * oriTransFrom[4] + offY * oriTransFrom[5]; subDs.SetGeoTransform(oriTransFrom); //////////// 把值写入子栅格 ///////////// subDs.GetRasterBand(1).WriteRaster ( 0, 0, subXcount, subYcount, oriValue, subXcount, subYcount, 0, 0 ); ///////////////// 返回子栅格路径 //////////////////// imgFilePaths.Add(imgFilePath); subDs.Dispose(); } } } else { imgFilePaths.Add(inPaht); } inDS.Dispose(); return(imgFilePaths); }
private static Bitmap getBitmapPaletteBuffered(Dataset ds) { Band band = ds.GetRasterBand(1); ColorTable ct = band.GetRasterColorTable(); if (ct == null) { return null; } if (ct.GetPaletteInterpretation() != PaletteInterp.GPI_RGB) { //MessageBox.Show(" Only RGB palette interp is supported by this sample!"); return null; } int width = band.XSize; int height = band.YSize; DateTime start = DateTime.Now; Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); byte[] r = new byte[width * height]; band.ReadRaster(0, 0, width, height, r, width, height, 0, 0); int i, j; for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { // entry c1 c2 c3 ColorEntry entry = ct.GetColorEntry(r[i + j * width]); int rColor = Convert.ToInt32(entry.c1); int gColor = Convert.ToInt32(entry.c2); int bColor = Convert.ToInt32(entry.c3); Color newColor = Color.FromArgb(rColor, gColor, bColor); bitmap.SetPixel(i, j, newColor); } } TimeSpan renderTime = DateTime.Now - start; double milliSeconds = renderTime.TotalMilliseconds; // ms //MessageBox.Show("GCI_PaletteIndex"); return bitmap; }
private static Bitmap CreateCompatibleBitmap(Dataset ds, int imageWidth, int imageHeight) { if (ds.RasterCount == 0) return null; bandMap = new int[4] { 1, 1, 1, 1 }; channelCount = 1; hasAlpha = false; isPremultiplied = false; isIndexed = false; channelSize = 8; // Evaluate the bands and find out a proper image transfer format for (int i = 0; i < ds.RasterCount; i++) { Band band = ds.GetRasterBand(i + 1); if (Gdal.GetDataTypeSize(band.DataType) > 8) channelSize = 16; // retrieving the premultiplied alpha flag string[] metadata = band.GetMetadata(""); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { if (metadata[iMeta].StartsWith("PREMULTIPLIED_ALPHA")) isPremultiplied = true; } switch (band.GetRasterColorInterpretation()) { case ColorInterp.GCI_AlphaBand: channelCount = 4; hasAlpha = true; bandMap[3] = i + 1; break; case ColorInterp.GCI_BlueBand: if (channelCount < 3) channelCount = 3; bandMap[0] = i + 1; break; case ColorInterp.GCI_RedBand: if (channelCount < 3) channelCount = 3; bandMap[2] = i + 1; break; case ColorInterp.GCI_GreenBand: if (channelCount < 3) channelCount = 3; bandMap[1] = i + 1; break; case ColorInterp.GCI_PaletteIndex: ct = band.GetRasterColorTable(); isIndexed = true; bandMap[0] = i + 1; break; case ColorInterp.GCI_GrayIndex: isIndexed = true; bandMap[0] = i + 1; break; default: // we create the bandmap using the dataset ordering by default if (i < 4 && bandMap[i] == 0) { if (channelCount < i) channelCount = i; bandMap[i] = i + 1; } break; } } // find out the pixel format based on the gathered information if (isIndexed) { pixelFormat = PixelFormat.Format8bppIndexed; dataType = DataType.GDT_Byte; pixelSpace = 1; } else { if (channelCount == 1) { if (channelSize > 8) { pixelFormat = PixelFormat.Format16bppGrayScale; dataType = DataType.GDT_Int16; pixelSpace = 2; } else { pixelFormat = PixelFormat.Format24bppRgb; channelCount = 3; dataType = DataType.GDT_Byte; pixelSpace = 3; } } else { if (hasAlpha) { if (channelSize > 8) { if (isPremultiplied) pixelFormat = PixelFormat.Format64bppArgb; else pixelFormat = PixelFormat.Format64bppPArgb; dataType = DataType.GDT_UInt16; pixelSpace = 8; } else { if (isPremultiplied) pixelFormat = PixelFormat.Format32bppPArgb; else pixelFormat = PixelFormat.Format32bppArgb; dataType = DataType.GDT_Byte; pixelSpace = 4; } channelCount = 4; } else { if (channelSize > 8) { pixelFormat = PixelFormat.Format48bppRgb; dataType = DataType.GDT_UInt16; pixelSpace = 6; } else { pixelFormat = PixelFormat.Format24bppRgb; dataType = DataType.GDT_Byte; pixelSpace = 3; } channelCount = 3; } } } // Create a Bitmap to store the GDAL image in return new Bitmap(imageWidth, imageHeight, pixelFormat); }
protected virtual void GetPreview(Dataset dataset, Size size, Graphics g, Envelope displayBbox, ProjectionInfo mapProjection, Map map) #endif { if (!NeedRotation(dataset)) { GetNonRotatedPreview(dataset, size, g, displayBbox, mapProjection); return; } var geoTransform = new GeoTransform(dataset); Bitmap bitmap = null; var bitmapTL = new Point(); //Coordinate imageTL = new Coordinate(), imageBR = new Coordinate(); //int bitmapWidth, bitmapHeight; var bitmapSize = new Size(); const int pixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((displayBbox.MinX > _envelope.MaxX) || (displayBbox.MaxX < _envelope.MinX) || (displayBbox.MaxY < _envelope.MinY) || (displayBbox.MinY > _envelope.MaxY)) return; // init histo Histogram = new List<int[]>(); for (int i = 0; i < Bands + 1; i++) Histogram.Add(new int[256]); // bounds of section of image to be displayed //var left = Math.Max(displayBbox.MinX, _envelope.MinX); //var top = Math.Min(displayBbox.MaxY, _envelope.MaxY); //var right = Math.Min(displayBbox.MaxX, _envelope.MaxX); //var bottom = Math.Max(displayBbox.MinY, _envelope.MinY); var trueImageBbox = displayBbox.Intersection(_envelope); // put display bounds into current projection Envelope shownImageBbox; if (Transform != null) { #if !DotSpatialProjections Transform.MathTransform.Invert(); shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, Transform.MathTransform); Transform.MathTransform.Invert(); #else shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, _transform.Source, _transform.Target); #endif } else { shownImageBbox = trueImageBbox; } // find min/max x and y pixels needed from image var g2i = geoTransform.GroundToImage(shownImageBbox).Intersection(new Envelope(0, _imageSize.Width, 0, _imageSize.Height)); var gdalImageRect = ToRectangle(g2i); var displayImageSize = gdalImageRect.Size; //// find ground coordinates of image pixels //var groundBR = geoTransform.ImageToGround(imageBR); //var groundTL = geoTransform.ImageToGround(imageTL); // convert ground coordinates to map coordinates to figure out where to place the bitmap var bitmapBR = new Point((int)map.WorldToImage(trueImageBbox.BottomRight()).X + 1, (int)map.WorldToImage(trueImageBbox.BottomRight()).Y + 1); bitmapTL = new Point((int)map.WorldToImage(trueImageBbox.TopLeft()).X, (int)map.WorldToImage(trueImageBbox.TopLeft()).Y); bitmapSize.Width = bitmapBR.X - bitmapTL.X; bitmapSize.Height = bitmapBR.Y - bitmapTL.Y; // check to see if image is on its side if (bitmapSize.Width > bitmapSize.Height && displayImageSize.Width < displayImageSize.Height) { displayImageSize.Width = bitmapSize.Height; displayImageSize.Height = bitmapSize.Width; } else { displayImageSize.Width = bitmapSize.Width; displayImageSize.Height = bitmapSize.Height; } // scale var bitScalar = GetBitScalar(); // 0 pixels in length or height, nothing to display if (bitmapSize.Width < 1 || bitmapSize.Height < 1) return; //initialize bitmap BitmapData bitmapData; bitmap = InitializeBitmap(bitmapSize, PixelFormat.Format24bppRgb, out bitmapData); /* bitmap = new Bitmap(bitmapLength, bitmapHeight, PixelFormat.Format24bppRgb); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmapLength, bitmapHeight), ImageLockMode.ReadWrite, bitmap.PixelFormat); */ try { unsafe { var cr = _noDataInitColor.R; var cg = _noDataInitColor.G; var cb = _noDataInitColor.B; /* functionality moved to InitializeBitmap // turn everything to _noDataInitColor, so we can make fill transparent for (int y = 0; y < bitmapHeight; y++) { byte* brow = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < bitmapLength; x++) { Int32 offsetX = x * 3; brow[offsetX++] = cb; brow[offsetX++] = cg; brow[offsetX] = cr; } } */ // create 3 dimensional buffer [band][x pixel][y pixel] //var tempBuffer = new double[Bands][]; var buffer = new double[Bands][][]; for (int i = 0; i < Bands; i++) { buffer[i] = new double[displayImageSize.Width][]; for (var j = 0; j < displayImageSize.Width; j++) buffer[i][j] = new double[displayImageSize.Height]; } //Band[] band = new Band[Bands]; var ch = new int[Bands]; // var noDataValues = new Double[Bands]; var scales = new Double[Bands]; ColorTable colorTable = null; var imageRect = gdalImageRect; ColorBlend colorBlend = null; var intermediateValue = new double[Bands]; // get data from image for (var i = 0; i < Bands; i++) { using (var band = dataset.GetRasterBand(i + 1)) { int hasVal; //get nodata value if present band.GetNoDataValue(out noDataValues[i], out hasVal); if (hasVal == 0) noDataValues[i] = Double.NaN; //Get the scale value if present band.GetScale(out scales[i], out hasVal); if (hasVal == 0) scales[i] = 1.0; switch (band.GetRasterColorInterpretation()) { case ColorInterp.GCI_BlueBand: ch[i] = 0; break; case ColorInterp.GCI_GreenBand: ch[i] = 1; break; case ColorInterp.GCI_RedBand: ch[i] = 2; break; case ColorInterp.GCI_Undefined: if (Bands > 1) ch[i] = 3; // infrared else { ch[i] = 4; colorBlend = GetColorBlend(band); intermediateValue = new Double[3]; } break; case ColorInterp.GCI_GrayIndex: ch[i] = 0; break; case ColorInterp.GCI_PaletteIndex: if (colorTable != null) { //this should not happen colorTable.Dispose(); } colorTable = band.GetRasterColorTable(); ch[i] = 5; intermediateValue = new Double[3]; break; default: ch[i] = -1; break; } } } // store these values to keep from having to make slow method calls var bitmapTLX = bitmapTL.X; var bitmapTLY = bitmapTL.Y; double imageTop = g2i.MinY; double imageLeft = g2i.MinX; double dblMapPixelWidth = map.PixelWidth; double dblMapPixelHeight = map.PixelHeight; double dblMapMinX = map.Envelope.MinX; double dblMapMaxY = map.Envelope.MaxY; // get inverse values var geoTop = geoTransform.Inverse[3]; var geoLeft = geoTransform.Inverse[0]; var geoHorzPixRes = geoTransform.Inverse[1]; var geoVertPixRes = geoTransform.Inverse[5]; var geoXRot = geoTransform.Inverse[2]; var geoYRot = geoTransform.Inverse[4]; var dblXScale = (g2i.Width) / (displayImageSize.Width - 1); var dblYScale = (g2i.Height) / (displayImageSize.Height - 1); // get inverse transform // NOTE: calling transform.MathTransform.Inverse() once and storing it // is much faster than having to call every time it is needed #if !DotSpatialProjections IMathTransform inverseTransform = null; if (Transform != null) inverseTransform = Transform.MathTransform.Inverse(); #endif var rowsRead = 0; var displayImageStep = displayImageSize.Height; while (rowsRead < displayImageSize.Height) { var rowsToRead = displayImageStep; if (rowsRead + rowsToRead > displayImageSize.Height) rowsToRead = displayImageSize.Height - rowsRead; var tempBuffer = new double[displayImageSize.Width * rowsToRead]; for (var i = 0; i < Bands; i++) { // read the buffer using (var band = dataset.GetRasterBand(i + 1)) { band.ReadRaster(imageRect.Left, imageRect.Top, imageRect.Width, imageRect.Height, tempBuffer, displayImageSize.Width, rowsToRead, 0, 0); } // parse temp buffer into the image x y value buffer long pos = 0; var newRowsRead = rowsRead + rowsToRead; for (var y = rowsRead; y < newRowsRead; y++) { for (var x = 0; x < displayImageSize.Width; x++) { buffer[i][x][y] = tempBuffer[pos++]; } } } rowsRead = rowsRead + rowsToRead; for (var pixY = 0d; pixY < bitmapBR.Y - bitmapTL.Y; pixY++) { var row = (byte*) bitmapData.Scan0 + ((int) Math.Round(pixY)*bitmapData.Stride); for (var pixX = 0; pixX < bitmapBR.X - bitmapTL.X; pixX++) { // same as Map.ImageToGround(), but much faster using stored values...rather than called each time var gndX = dblMapMinX + (pixX + bitmapTLX)*dblMapPixelWidth; var gndY = dblMapMaxY - (pixY + bitmapTLY)*dblMapPixelHeight; // transform ground point if needed if (Transform != null) { #if !DotSpatialProjections var dblPoint = inverseTransform.Transform(new[] {gndX, gndY}); #else dblPoint = new double[] { GndX, GndY }; Reproject.ReprojectPoints(dblPoint, null, _transform.Source, _transform.Target, 0, 1); #endif gndX = dblPoint[0]; gndY = dblPoint[1]; } // same as GeoTransform.GroundToImage(), but much faster using stored values... var imageCoord = new Coordinate( geoLeft + geoHorzPixRes*gndX + geoXRot*gndY, geoTop + geoYRot*gndX + geoVertPixRes*gndY); if (!g2i.Contains(imageCoord)) continue; var imagePt = new Point((int)((imageCoord.X - imageLeft) / dblXScale), (int)((imageCoord.Y - imageTop) / dblYScale)); // Apply color correction for (var i = 0; i < Bands; i++) { intermediateValue[i] = buffer[i][imagePt.X][imagePt.Y]; // apply scale intermediateValue[i] *= scales[i]; double spotVal; var imageVal = spotVal = intermediateValue[i] = intermediateValue[i]/bitScalar; if (ch[i] == 4) { if (imageVal != noDataValues[i]) { var color = colorBlend.GetColor(Convert.ToSingle(imageVal)); intermediateValue[0] = color.B; intermediateValue[1] = color.G; intermediateValue[2] = color.R; //intVal[3] = ce.c4; } else { intermediateValue[0] = cb; intermediateValue[1] = cg; intermediateValue[2] = cr; } } else if (ch[i] == 5 && colorTable != null) { if (imageVal != noDataValues[i]) { using (var ce = colorTable.GetColorEntry(Convert.ToInt32(imageVal))) { intermediateValue[0] = ce.c3; intermediateValue[1] = ce.c2; intermediateValue[2] = ce.c1; //intVal[3] = ce.c4; } } else { intermediateValue[0] = cb; intermediateValue[1] = cg; intermediateValue[2] = cr; } } else { if (ColorCorrect) { intermediateValue[i] = ApplyColorCorrection(imageVal, spotVal, ch[i], gndX, gndY); // if pixel is within ground boundary, add its value to the histogram if (ch[i] != -1 && intermediateValue[i] > 0 && (HistoBounds.Bottom >= (int) gndY) && HistoBounds.Top <= (int) gndY && HistoBounds.Left <= (int) gndX && HistoBounds.Right >= (int) gndX) { Histogram[ch[i]][(int) intermediateValue[i]]++; } } if (intermediateValue[i] > 255) intermediateValue[i] = 255; } } // luminosity if (Bands >= 3) Histogram[Bands][ (int) (intermediateValue[2]*0.2126 + intermediateValue[1]*0.7152 + intermediateValue[0]*0.0722)] ++; WritePixel(pixX, intermediateValue, pixelSize, ch, row); } } } if (colorTable != null) { colorTable.Dispose(); } } } finally { bitmap.UnlockBits(bitmapData); } } //using (var ia = new ImageAttributes()) //{ // var colorMap = new[] // { // new ColorMap {OldColor = _noDataInitColor, NewColor = Color.Transparent}, // new ColorMap {OldColor = TransparentColor, NewColor = Color.Transparent} // }; // // ia.SetRemapTable(colorMap, ColorAdjustType.Bitmap); bitmap.MakeTransparent(_noDataInitColor); if (TransparentColor != Color.Empty) bitmap.MakeTransparent(TransparentColor); g.DrawImage(bitmap, bitmapTL); //} }
private static void SaveBitmapBuffered(Dataset ds, string filename, int iOverview) { // Get the GDAL Band objects from the Dataset Band redBand = ds.GetRasterBand(1); if (redBand.GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex) { SaveBitmapPaletteBuffered(ds, filename, iOverview); return; } if (redBand.GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) { SaveBitmapGrayBuffered(ds, filename, iOverview); return; } 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); } if (iOverview >= 0 && redBand.GetOverviewCount() > iOverview) redBand = redBand.GetOverview(iOverview); 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; } if (iOverview >= 0 && greenBand.GetOverviewCount() > iOverview) greenBand = greenBand.GetOverview(iOverview); 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; } if (iOverview >= 0 && blueBand.GetOverviewCount() > iOverview) blueBand = blueBand.GetOverview(iOverview); // Get the width and height of the raster 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); }
/// <summary> /// Attempts to open the specified file. /// </summary> public override void Open() { try { _dataset = Gdal.Open(Filename, Access.GA_Update); } catch { try { _dataset = Gdal.Open(Filename, Access.GA_ReadOnly); } catch (Exception ex) { throw new GdalException(ex.ToString()); } } _red = _dataset.GetRasterBand(1); if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_PaletteIndex) { ReadPaletteBuffered(); } if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) { ReadGrayIndex(); } if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) { ReadRGB(); } if (_red.GetRasterColorInterpretation() == ColorInterp.GCI_AlphaBand) { ReadARGB(); } }
private static void SaveBitmapGrayBuffered(Dataset ds, string filename, int iOverview) { // Get the GDAL Band objects from the Dataset Band band = ds.GetRasterBand(1); if (iOverview >= 0 && band.GetOverviewCount() > iOverview) band = band.GetOverview(iOverview); // Get the width and height of the Dataset int width = band.XSize; int height = band.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]; band.ReadRaster(0, 0, width, height, r, 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(r[i+j*width]), Convert.ToInt32(r[i+j*width])); bitmap.SetPixel(i, j, newColor); } } bitmap.Save(filename); }
protected virtual void GetPreview(Dataset dataset, Size size, Graphics g, Envelope displayBbox, ProjectionInfo mapProjection, Map map) #endif { DateTime drawStart = DateTime.Now; double totalReadDataTime = 0; double totalTimeSetPixel = 0; if (!NeedRotation(dataset)) { GetNonRotatedPreview(dataset, size, g, displayBbox, mapProjection); return; } var geoTransform = new GeoTransform(dataset); Bitmap bitmap = null; var bitmapTl = new Point(); var bitmapSize = new Size(); const int pixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((displayBbox.MinX > _envelope.MaxX) || (displayBbox.MaxX < _envelope.MinX) || (displayBbox.MaxY < _envelope.MinY) || (displayBbox.MinY > _envelope.MaxY)) return; // init histo Histogram = new List<int[]>(); for (int i = 0; i < Bands + 1; i++) Histogram.Add(new int[256]); var trueImageBbox = displayBbox.Intersection(_envelope); // put display bounds into current projection Envelope shownImageBbox = trueImageBbox; #if !DotSpatialProjections if (ReverseCoordinateTransformation != null) { shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, ReverseCoordinateTransformation.MathTransform); } #else if (CoordinateTransformation != null) { shownImageBbox = GeometryTransform.TransformBox(trueImageBbox, CoordinateTransformation.Target, CoordinateTransformation.Source); } #endif // find min/max x and y pixels needed from image var g2I = geoTransform.GroundToImage(shownImageBbox).Intersection(new Envelope(0, _imageSize.Width, 0, _imageSize.Height)); var gdalImageRect = ToRectangle(g2I); var displayImageSize = gdalImageRect.Size; // convert ground coordinates to map coordinates to figure out where to place the bitmap var bitmapBr = new Point((int)map.WorldToImage(trueImageBbox.BottomRight()).X + 1, (int)map.WorldToImage(trueImageBbox.BottomRight()).Y + 1); bitmapTl = new Point((int)map.WorldToImage(trueImageBbox.TopLeft()).X, (int)map.WorldToImage(trueImageBbox.TopLeft()).Y); bitmapSize.Width = bitmapBr.X - bitmapTl.X; bitmapSize.Height = bitmapBr.Y - bitmapTl.Y; // check to see if image is on its side if (bitmapSize.Width > bitmapSize.Height && displayImageSize.Width < displayImageSize.Height) { displayImageSize.Width = bitmapSize.Height; displayImageSize.Height = bitmapSize.Width; } else { displayImageSize.Width = bitmapSize.Width; displayImageSize.Height = bitmapSize.Height; } // scale var bitScalar = GetBitScalar(); // 0 pixels in length or height, nothing to display if (bitmapSize.Width < 1 || bitmapSize.Height < 1) return; //initialize bitmap BitmapData bitmapData; bitmap = InitializeBitmap(bitmapSize, PixelFormat.Format24bppRgb, out bitmapData); try { unsafe { var cr = _noDataInitColor.R; var cg = _noDataInitColor.G; var cb = _noDataInitColor.B; // create 3 dimensional buffer [band][x pixel][y pixel] var buffer = new double[Bands][][]; for (int i = 0; i < Bands; i++) { buffer[i] = new double[displayImageSize.Width][]; for (var j = 0; j < displayImageSize.Width; j++) buffer[i][j] = new double[displayImageSize.Height]; } var ch = new int[Bands]; var noDataValues = new Double[Bands]; var scales = new Double[Bands]; ColorTable colorTable = null; short[][] colorTableCache = null; var imageRect = gdalImageRect; ColorBlend colorBlend = null; var intermediateValue = new double[Bands]; // get data from image for (var i = 0; i < Bands; i++) { using (var band = dataset.GetRasterBand(i + 1)) { int hasVal; //get nodata value if present band.GetNoDataValue(out noDataValues[i], out hasVal); if (hasVal == 0) noDataValues[i] = Double.NaN; //Get the scale value if present band.GetScale(out scales[i], out hasVal); if (hasVal == 0) scales[i] = 1.0; switch (band.GetRasterColorInterpretation()) { case ColorInterp.GCI_BlueBand: ch[i] = 0; break; case ColorInterp.GCI_GreenBand: ch[i] = 1; break; case ColorInterp.GCI_RedBand: ch[i] = 2; break; case ColorInterp.GCI_Undefined: if (Bands > 1) ch[i] = 3; // infrared else { ch[i] = 4; colorBlend = GetColorBlend(band); intermediateValue = new Double[3]; } break; case ColorInterp.GCI_GrayIndex: ch[i] = 0; break; case ColorInterp.GCI_PaletteIndex: if (colorTable != null) { //this should not happen colorTable.Dispose(); } colorTable = band.GetRasterColorTable(); int numColors = colorTable.GetCount(); colorTableCache = new short[numColors][]; for (int col = 0; col < numColors; col++) { using (var colEntry = colorTable.GetColorEntry(col)) { colorTableCache[col] = new short[]{ colEntry.c1, colEntry.c2, colEntry.c3 }; } } ch[i] = 5; intermediateValue = new Double[3]; break; default: ch[i] = -1; break; } } } // store these values to keep from having to make slow method calls var bitmapTlx = bitmapTl.X; var bitmapTly = bitmapTl.Y; double imageTop = g2I.MinY; double imageLeft = g2I.MinX; double dblMapPixelWidth = map.PixelWidth; double dblMapPixelHeight = map.PixelHeight; double dblMapMinX = map.Envelope.MinX; double dblMapMaxY = map.Envelope.MaxY; // get inverse values var geoTop = geoTransform.Inverse[3]; var geoLeft = geoTransform.Inverse[0]; var geoHorzPixRes = geoTransform.Inverse[1]; var geoVertPixRes = geoTransform.Inverse[5]; var geoXRot = geoTransform.Inverse[2]; var geoYRot = geoTransform.Inverse[4]; var dblXScale = (g2I.Width) / (displayImageSize.Width - 1); var dblYScale = (g2I.Height) / (displayImageSize.Height - 1); // get inverse transform // NOTE: calling transform.MathTransform.Inverse() once and storing it // is much faster than having to call every time it is needed #if !DotSpatialProjections IMathTransform inverseTransform = null; if (ReverseCoordinateTransformation != null) inverseTransform = ReverseCoordinateTransformation.MathTransform; #else DotSpatial.Projections.ICoordinateTransformation inverseTransform = null; if (CoordinateTransformation != null) { inverseTransform = new DotSpatial.Projections.CoordinateTransformation { Source = CoordinateTransformation.Target, Target = CoordinateTransformation.Source }; } #endif var rowsRead = 0; var displayImageStep = displayImageSize.Height; while (rowsRead < displayImageStep) { var rowsToRead = displayImageStep; if (rowsRead + rowsToRead > displayImageStep) rowsToRead = displayImageStep - rowsRead; var tempBuffer = new double[displayImageSize.Width * rowsToRead]; for (var i = 0; i < Bands; i++) { // read the buffer using (var band = dataset.GetRasterBand(i + 1)) { DateTime start = DateTime.Now; band.ReadRaster(imageRect.Left, imageRect.Top, imageRect.Width, imageRect.Height, tempBuffer, displayImageSize.Width, rowsToRead, 0, 0); if (_logger.IsDebugEnabled) { TimeSpan took = DateTime.Now - start; totalReadDataTime += took.TotalMilliseconds; } } // parse temp buffer into the image x y value buffer long pos = 0; var newRowsRead = rowsRead + rowsToRead; for (var y = rowsRead; y < newRowsRead; y++) { for (var x = 0; x < displayImageSize.Width; x++) { buffer[i][x][y] = tempBuffer[pos++]; } } } rowsRead = rowsRead + rowsToRead; for (var pixY = 0d; pixY < bitmapBr.Y - bitmapTl.Y; pixY++) { var row = (byte*) bitmapData.Scan0 + ((int) Math.Round(pixY)*bitmapData.Stride); for (var pixX = 0; pixX < bitmapBr.X - bitmapTl.X; pixX++) { // same as Map.ImageToGround(), but much faster using stored values...rather than called each time var gndX = dblMapMinX + (pixX + bitmapTlx)*dblMapPixelWidth; var gndY = dblMapMaxY - (pixY + bitmapTly)*dblMapPixelHeight; // transform ground point if needed if (inverseTransform != null) { #if !DotSpatialProjections var dblPoint = inverseTransform.Transform(new[] {gndX, gndY}); #else var dblPoint = new double[] { gndX, gndY }; Reproject.ReprojectPoints(dblPoint, null, inverseTransform.Source, inverseTransform.Target, 0, 1); #endif gndX = dblPoint[0]; gndY = dblPoint[1]; } // same as GeoTransform.GroundToImage(), but much faster using stored values... var imageCoord = new Coordinate( geoLeft + geoHorzPixRes*gndX + geoXRot*gndY, geoTop + geoYRot*gndX + geoVertPixRes*gndY); if (!g2I.Contains(imageCoord)) continue; var imagePt = new Point((int)((imageCoord.X - imageLeft) / dblXScale), (int)((imageCoord.Y - imageTop) / dblYScale)); // Apply color correction for (var i = 0; i < Bands; i++) { intermediateValue[i] = buffer[i][imagePt.X][imagePt.Y]; // apply scale intermediateValue[i] *= scales[i]; double spotVal; var imageVal = spotVal = intermediateValue[i] = intermediateValue[i]/bitScalar; if (ch[i] == 4) { if (!DoublesAreEqual(imageVal,noDataValues[i])) { var color = colorBlend.GetColor(Convert.ToSingle(imageVal)); intermediateValue[0] = color.B; intermediateValue[1] = color.G; intermediateValue[2] = color.R; //intVal[3] = ce.c4; } else { intermediateValue[0] = cb; intermediateValue[1] = cg; intermediateValue[2] = cr; } } else if (ch[i] == 5 && colorTable != null) { if (double.IsNaN(noDataValues[i]) || !DoublesAreEqual(imageVal, noDataValues[i])) { var ce = colorTableCache[Convert.ToInt32(imageVal)]; intermediateValue[0] = ce[2]; intermediateValue[1] = ce[1]; intermediateValue[2] = ce[0]; } else { intermediateValue[0] = cb; intermediateValue[1] = cg; intermediateValue[2] = cr; } } else { if (ColorCorrect) { intermediateValue[i] = ApplyColorCorrection(imageVal, spotVal, ch[i], gndX, gndY); // if pixel is within ground boundary, add its value to the histogram if (ch[i] != -1 && intermediateValue[i] > 0 && (HistoBounds.Bottom >= (int) gndY) && HistoBounds.Top <= (int) gndY && HistoBounds.Left <= (int) gndX && HistoBounds.Right >= (int) gndX) { Histogram[ch[i]][(int) intermediateValue[i]]++; } } if (intermediateValue[i] > 255) intermediateValue[i] = 255; } } // luminosity if (Bands >= 3) Histogram[Bands][ (int) (intermediateValue[2]*0.2126 + intermediateValue[1]*0.7152 + intermediateValue[0]*0.0722)] ++; DateTime writeStart = DateTime.MinValue; if (_logger.IsDebugEnabled) writeStart = DateTime.Now; WritePixel(pixX, intermediateValue, pixelSize, ch, row); if (_logger.IsDebugEnabled) { TimeSpan took = DateTime.Now - writeStart; totalTimeSetPixel += took.TotalMilliseconds; } } } } if (colorTable != null) { colorTable.Dispose(); } } } finally { bitmap.UnlockBits(bitmapData); } } DateTime drawGdiStart = DateTime.Now; bitmap.MakeTransparent(_noDataInitColor); if (TransparentColor != Color.Empty) bitmap.MakeTransparent(TransparentColor); g.DrawImage(bitmap, bitmapTl); if (_logger.IsDebugEnabled) { TimeSpan took = DateTime.Now - drawStart; TimeSpan drawGdiTook = DateTime.Now - drawGdiStart; _logger.DebugFormat("Draw GdalImage in {0}ms, readTime: {1}, setPixelTime: {2}, drawTime: {3}", took.TotalMilliseconds, totalReadDataTime, totalTimeSetPixel, drawGdiTook.TotalMilliseconds); } }
private static void SaveBitmapGrayDirect(Dataset ds, string filename, int iOverview) { // Get the GDAL Band objects from the Dataset Band band = ds.GetRasterBand(1); if (iOverview >= 0 && band.GetOverviewCount() > iOverview) band = band.GetOverview(iOverview); // Get the width and height of the Dataset int width = band.XSize; int height = band.YSize; // Create a Bitmap to store the GDAL image in Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed); DateTime start = DateTime.Now; byte[] r = new byte[width * height]; band.ReadRaster(0, 0, width, height, r, width, height, 0, 0); // Use GDAL raster reading methods to read the image data directly into the Bitmap BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); try { ColorPalette pal = bitmap.Palette; for(int i = 0; i < 256; i++) pal.Entries[i] = Color.FromArgb( 255, i, i, i ); bitmap.Palette = pal; int stride = bitmapData.Stride; IntPtr buf = bitmapData.Scan0; band.ReadRaster(0, 0, width, height, buf, width, height, DataType.GDT_Byte, 1, stride); TimeSpan renderTime = DateTime.Now - start; Console.WriteLine("SaveBitmapDirect fetch time: " + renderTime.TotalMilliseconds + " ms"); } finally { bitmap.UnlockBits(bitmapData); } bitmap.Save(filename); }