예제 #1
0
        /// <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;
            }
        }