/// <summary> /// 读取栅格块为字节数组(自动拉伸) /// </summary> /// <param name="band"></param> /// <param name="xOffset"></param> /// <param name="yOffset"></param> /// <param name="xSize"></param> /// <param name="ySize"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public static byte[] ReadBand(this Band band, int xOffset, int yOffset, int xSize, int ySize, int width, int height) { byte[] buffer = null; if (band == null || width == 0 || height == 0) { return(buffer); } int length = width * height; DataType dataType = band.DataType; IntPtr bufferPtr; // Percentage truncation double minPercent = 0.5; double maxPercent = 0.5; band.GetMaximum(out double maxValue, out int hasvalue); band.GetMinimum(out double minValue, out hasvalue); double dValue = maxValue - minValue; double highValue = maxValue - dValue * maxPercent / 100; double lowValue = minValue + dValue * minPercent / 100; double factor = 255 / (highValue - lowValue); // 系数 CPLErr err = CPLErr.CE_None; lock (_lockObj) { switch (dataType) { case DataType.GDT_Unknown: throw new Exception("Unknown datatype"); case DataType.GDT_Byte: { buffer = new byte[length]; bufferPtr = GCHandleHelper.GetIntPtr(buffer); err = band.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, 0, 0); //for (int i = 0; i < length; i++) //{ // buffer[i] = buffer[i].StretchToByteValue(highValue, lowValue, factor);//做拉伸时才需要 //} } break; case DataType.GDT_UInt16: { ushort[] tmpBuffer = new ushort[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = band.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, 0, 0); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Int16: { short[] tmpBuffer = new short[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = band.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, 0, 0); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_UInt32: { uint[] tmpBuffer = new uint[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = band.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, 0, 0); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Int32: { int[] tmpBuffer = new int[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = band.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, 0, 0); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Float32: { float[] tmpBuffer = new float[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = band.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, 0, 0); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Float64: { double[] tmpBuffer = new double[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = band.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, 0, 0); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_CInt16: case DataType.GDT_CInt32: case DataType.GDT_CFloat32: case DataType.GDT_CFloat64: case DataType.GDT_TypeCount: throw new NotImplementedException(); } } return(buffer); }
/// <summary> /// 按照BGR(A)顺序读取栅格并返回位图的字节数组 /// </summary> /// <param name="dataset">栅格数据集</param> /// <param name="xOffset">X偏移</param> /// <param name="yOffset">Y偏移</param> /// <param name="xSize">X宽度</param> /// <param name="ySize">Y宽度</param> /// <param name="width">位图长度</param> /// <param name="height">位图宽度</param> /// <param name="bandCount">波段数</param> /// <param name="bandMap">波段映射</param> /// <param name="pixelSpace">像素间隔</param> /// <param name="lineSpace">行间隔</param> /// <param name="bandSpace">波段间隔</param> /// <param name="readABand">是否读取透明波段</param> /// <returns>位图的字节数组</returns> public static byte[] ReadBmpBytes(this Dataset dataset, int xOffset, int yOffset, int xSize, int ySize, int width, int height, int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, bool readABand = false) { byte[] buffer = null; if (dataset == null || xOffset < 0 || yOffset < 0 || xSize <= 0 || ySize <= 0 || width <= 0 || height <= 0 || dataset.RasterXSize < (xOffset + xSize) || dataset.RasterYSize < (yOffset + ySize)) { return(buffer); } int destBandCount; if (readABand) { destBandCount = 4; } else { destBandCount = 3; } if (dataset.RasterCount < destBandCount || bandCount != destBandCount || bandMap?.Length != destBandCount) { return(buffer); } int length = width * height * bandCount; DataType dataType; double maxValue, minValue; using (var band = dataset.GetRasterBand(1)) { dataType = band.DataType; band.GetMaximum(out maxValue, out int hasvalue); band.GetMinimum(out minValue, out hasvalue); } IntPtr bufferPtr; // Percentage truncation double minPercent = 0.5; double maxPercent = 0.5; double dValue = maxValue - minValue; double highValue = maxValue - dValue * maxPercent / 100; double lowValue = minValue + dValue * minPercent / 100; double factor = 255 / (highValue - lowValue); // 系数 CPLErr err = CPLErr.CE_None; lock (_lockObj) { switch (dataType) { case DataType.GDT_Unknown: throw new Exception("Unknown datatype"); case DataType.GDT_Byte: { buffer = new byte[length]; bufferPtr = GCHandleHelper.GetIntPtr(buffer); err = dataset.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, bandCount, bandMap, pixelSpace, lineSpace, bandSpace); //for (int i = 0; i < length; i++) //{ // buffer[i] = buffer[i].StretchToByteValue(highValue, lowValue, factor);//做拉伸时才需要 //} } break; case DataType.GDT_UInt16: { ushort[] tmpBuffer = new ushort[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = dataset.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, bandCount, bandMap, pixelSpace, lineSpace, bandSpace); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Int16: { short[] tmpBuffer = new short[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = dataset.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, bandCount, bandMap, pixelSpace, lineSpace, bandSpace); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_UInt32: { uint[] tmpBuffer = new uint[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = dataset.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, bandCount, bandMap, pixelSpace, lineSpace, bandSpace); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Int32: { int[] tmpBuffer = new int[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = dataset.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, bandCount, bandMap, pixelSpace, lineSpace, bandSpace); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Float32: { float[] tmpBuffer = new float[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = dataset.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, bandCount, bandMap, pixelSpace, lineSpace, bandSpace); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_Float64: { double[] tmpBuffer = new double[length]; bufferPtr = GCHandleHelper.GetIntPtr(tmpBuffer); err = dataset.ReadRaster(xOffset, yOffset, xSize, ySize, bufferPtr, width, height, dataType, bandCount, bandMap, pixelSpace, lineSpace, bandSpace); buffer = new byte[length]; for (int i = 0; i < length; i++) { buffer[i] = tmpBuffer[i].StretchToByteValue(highValue, lowValue, factor); } } break; case DataType.GDT_CInt16: case DataType.GDT_CInt32: case DataType.GDT_CFloat32: case DataType.GDT_CFloat64: case DataType.GDT_TypeCount: throw new NotImplementedException(); } } return(buffer); }