/// <summary> /// TRANSPOSE ARRAY /// </summary> /// <param name="pixelblock">PixelBlock of data values</param> /// <param name="noDataValue">Default NoData value</param> /// <returns>Array of values transposed</returns> internal static Array TransposeArray(IPixelBlock3 pixelblock, object noDataValue) { System.Array oldArray = (System.Array)pixelblock.get_PixelData(0); int cols = oldArray.GetLength(0); int rows = oldArray.GetLength(1); System.Array newArray = System.Array.CreateInstance(oldArray.GetType().GetElementType(), rows, cols); for (int col = 0; col < cols; col++) { for (int row = 0; row < rows; row++) { object noDataMaskValue = pixelblock.GetNoDataMaskVal(0, col, row); object pixelValue = (Convert.ToByte(noDataMaskValue, CultureInfo.InvariantCulture) == 1) ? oldArray.GetValue(col, row) : noDataValue; newArray.SetValue(pixelValue, row, col); } } return(newArray); }
/// <summary> /// Read pixels from the input Raster and fill the PixelBlock provided with processed pixels. /// The RasterFunctionHelper object is used to handle pixel type conversion and resampling. /// The watermark image is then blended to the bottom right corner of the pixel block. /// </summary> /// <param name="pTlc">Point to start the reading from in the Raster</param> /// <param name="pRaster">Reference Raster for the PixelBlock</param> /// <param name="pPixelBlock">PixelBlock to be filled in</param> public void Read(IPnt pTlc, IRaster pRaster, IPixelBlock pPixelBlock) { BitmapData wMBitmapData = null; double pixelValue = 0.0; int wmRow = 0; int wmCol = 0; try { // Call Read method of the Raster Function Helper object. myFunctionHelper.Read(pTlc, null, pRaster, pPixelBlock); int wMBandOffset = 0; #region Reference Raster Properties // Get the pixel type of the reference raster to see if // it is compatible (8 bit). IRasterProps referenceProps = (IRasterProps)pRaster; if (referenceProps.PixelType != rstPixelType.PT_UCHAR && referenceProps.PixelType != rstPixelType.PT_CHAR) { throw new System.Exception( "Function can only be applied to 8bit data."); } #endregion #region Load watermark image object // Create new image object for the watermark image. myWatermarkImage = new Bitmap(myWatermarkImagePath); // Read number of bands of the watermark image. if (myWatermarkImage.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb) { wMBandOffset = 4; } else { if (myWatermarkImage.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb) { wMBandOffset = 3; } else { throw new System.Exception( "Invalid bitmap. Please provide one with 8bits per band in ARGB or RGB format."); } } #endregion int pBHeight = pPixelBlock.Height; int pBWidth = pPixelBlock.Width; int wMHeight = myWatermarkImage.Height; int wMWidth = myWatermarkImage.Width; int x_gap = xgap; int y_gap = ygap; #region Prepare Watermark Image for reading // Get the pixels from the watermark image using the lockbits function. wMBitmapData = myWatermarkImage.LockBits(new Rectangle(0, 0, wMWidth, wMHeight), ImageLockMode.ReadOnly, myWatermarkImage.PixelFormat); System.IntPtr wMScan0 = wMBitmapData.Scan0; int wMStride = wMBitmapData.Stride; #endregion // The unsafe keyword is used so that pointers can be used to access pixels // from the watermark image. unsafe { int wMPaddingOffset = wMStride - (wMWidth * wMBandOffset); // Start filling from the correct row, col in the pixelblock // using the indices calculated above System.Array pixelValues; if (pPixelBlock.Planes == 3) { if (wMBandOffset == 4) // To check for transparency in WM Image { #region 3 Band PixelBlock for (int nBand = 0; nBand < pPixelBlock.Planes; ++nBand) { IPixelBlock3 ipPixelBlock = (IPixelBlock3)pPixelBlock; pixelValues = (System.Array)(ipPixelBlock.get_PixelData(nBand)); byte *wMStartByte = (byte *)(void *)wMScan0; wmRow = 0; for (int i = 0; i < pBHeight; i++) { wmCol = 0; byte *wMColStartByte = wMStartByte; for (int k = 0; k < pBWidth; k++) { pixelValue = Convert.ToDouble(pixelValues.GetValue(k, i)); if (Convert.ToDouble(wMStartByte[3]) != 0.0 && Convert.ToByte(ipPixelBlock.GetNoDataMaskVal(nBand, k, i)) == 1) { // Blend the pixelValue from the PixelBlock with the corresponding // pixel from the watermark image. pixelValue = ((1 - blendValue) * pixelValue) + (blendValue * Convert.ToDouble(wMStartByte[2 - nBand])); pixelValues.SetValue(Convert.ToByte(pixelValue), k, i); } if (wmCol == wMWidth - 1) { wmCol = 0; wMStartByte = wMColStartByte; k += x_gap; } else { ++wmCol; wMStartByte += wMBandOffset; } } wMStartByte = wMColStartByte + wMWidth * wMBandOffset; if (wmRow == wMHeight - 1) { wmRow = 0; wMStartByte = (byte *)(void *)wMScan0; i += y_gap; } else { ++wmRow; wMStartByte += wMPaddingOffset; } } ((IPixelBlock3)pPixelBlock).set_PixelData(nBand, pixelValues); } #endregion } } } #region Cleanup myWatermarkImage.UnlockBits(wMBitmapData); myWatermarkImage.Dispose(); myWatermarkImage = null; wMBitmapData = null; wMScan0 = (System.IntPtr)null; wMStride = 0; #endregion } catch (Exception exc) { #region Cleanup if (wMBitmapData != null) { myWatermarkImage.UnlockBits(wMBitmapData); } wMBitmapData = null; if (myWatermarkImage != null) { myWatermarkImage.Dispose(); } myWatermarkImage = null; #endregion System.Exception myExc = new System.Exception( "Exception caught in Read method of Watermark Function. " + exc.Message, exc); throw myExc; } }
/// <summary> /// Read pixels from the input Raster and fill the PixelBlock provided with processed pixels. /// </summary> /// <param name="pTlc">Point to start the reading from in the Raster</param> /// <param name="pRaster">Reference Raster for the PixelBlock</param> /// <param name="pPixelBlock">PixelBlock to be filled in</param> public void Read(IPnt pTlc, IRaster pRaster, IPixelBlock pPixelBlock) { try { // Create a new pixel block to read the input data into. // This is done because the pPixelBlock represents the output // pixel block which is different from the input. int pBHeight = pPixelBlock.Height; int pBWidth = pPixelBlock.Width; IPnt pBlockSize = new Pnt(); pBlockSize.X = pBWidth; pBlockSize.Y = pBHeight; IPixelBlock inputPixelBlock = new PixelBlock(); ((IPixelBlock4)inputPixelBlock).Create(myInpNumBands, pBWidth, pBHeight, myInpPixeltype); // Call Read method of the Raster Function Helper object to read the input pixels into // the inputPixelBlock. myFunctionHelper.Read(pTlc, null, pRaster, inputPixelBlock); System.Array inpPixelValues1; System.Array inpPixelValues2; System.Array outPixelValues; int index1 = Convert.ToInt16(myBandIndices[0]) - 1;; // Get NIR band index specified by user. int index2 = Convert.ToInt16(myBandIndices[1]) - 1;; // Get Red Band index specified by user. // Get the correct bands from the input. IPixelBlock3 ipPixelBlock = (IPixelBlock3)inputPixelBlock; inpPixelValues1 = (System.Array)(ipPixelBlock.get_PixelData(index1)); inpPixelValues2 = (System.Array)(ipPixelBlock.get_PixelData(index2)); outPixelValues = (System.Array)(((IPixelBlock3)pPixelBlock).get_PixelData(0)); int i = 0; int k = 0; double pixelValue = 0.0; double nirValue = 0.0; double irValue = 0.0; // Perform the NDVI computation and store the result in the output pixel block. for (i = 0; i < pBHeight; i++) { for (k = 0; k < pBWidth; k++) { nirValue = Convert.ToDouble(inpPixelValues1.GetValue(k, i)); irValue = Convert.ToDouble(inpPixelValues2.GetValue(k, i)); // Check if input is not NoData. if ((Convert.ToByte(ipPixelBlock.GetNoDataMaskVal(index1, k, i)) == 1) && Convert.ToByte(ipPixelBlock.GetNoDataMaskVal(index2, k, i)) == 1) { // NDVI[k] = (NIR[k]-Red[k])/(NIR[k]+Red[k]); if ((nirValue + irValue) != 0) // Check for division by 0. { pixelValue = (nirValue - irValue) / (nirValue + irValue); if (pixelValue < -1.0 || pixelValue > 1.0) { pixelValue = 0.0; } } else { pixelValue = 0.0; } } outPixelValues.SetValue((float)(pixelValue), k, i); } } // Set the output pixel values on the output pixel block. ((IPixelBlock3)pPixelBlock).set_PixelData(0, outPixelValues); // Copy over the NoData mask from the input and set it on the output. ((IPixelBlock3)pPixelBlock).set_NoDataMask(0, ((IPixelBlock3)inputPixelBlock).get_NoDataMask(0)); } catch (Exception exc) { System.Exception myExc = new System.Exception( "Exception caught in Read method: " + exc.Message, exc); throw myExc; } }