This document is archived and information here might be outdated.  Recommended version.


How to access pixel data using the RawBlocks object (ArcObjects .NET 10.5 SDK)

How to access pixel data using the RawBlocks object


Summary
Raster pixels can be accessed through the IRasterEdit and IPixelBlock3 interfaces. These interfaces read and edit pixels on raster objects. The RawBlocks object, new at ArcGIS 10, works with pixels on a raster band. It reads pixels using an internal tiling structure and loops through the pixel blocks without resampling.
This topic shows how to use the RawBlocks object to manipulate raster data at a pixel level.

Accessing pixel data using the RawBlocks object

To iterate through pixel blocks and pixel values to change the pixel values and persist the changes in the raster dataset using the RawBlocks object, see the following code example:
[C#]
public static void ReadWriteRawBlocks(IRasterDataset rasDs)
{
    IRasterBandCollection rasBandCol=(IRasterBandCollection)rasDs;
    IRawBlocks rawBlocks;
    IRasterInfo rasInfo;
    IPixelBlock pb;

    // Iterate through each band of the dataset.
    for (int m=0; m <= rasBandCol.Count - 1; m++)
    {
        // QI to IRawBlocks from IRasterBandCollection.
        rawBlocks=(IRawBlocks)rasBandCol.Item(m);
        rasInfo=rawBlocks.RasterInfo;
        // Create the pixel block.
        pb=rawBlocks.CreatePixelBlock();

        // Determine the tiling scheme for the raster dataset.

        int bStartX=(int)Math.Floor((rasInfo.Extent.Envelope.XMin -
            rasInfo.Origin.X) / (rasInfo.BlockWidth * rasInfo.CellSize.X));
        int bEndX=(int)Math.Ceiling((rasInfo.Extent.Envelope.XMax -
            rasInfo.Origin.X) / (rasInfo.BlockWidth * rasInfo.CellSize.X));
        int bStartY=(int)Math.Floor((rasInfo.Origin.Y -
            rasInfo.Extent.Envelope.YMax) / (rasInfo.BlockHeight *
            rasInfo.CellSize.Y));
        int bEndY=(int)Math.Ceiling((rasInfo.Origin.Y -
            rasInfo.Extent.Envelope.YMin) / (rasInfo.BlockHeight *
            rasInfo.CellSize.Y));

        // Iterate through the pixel blocks.
        for (int pbYcursor=startY; pbYcursor < endY; pbYcursor++)
        {
            for (int pbXcursor=startX; pbXcursor < endX; pbXcursor++)
            {
                // Get the pixel block.
                rawBlocks.ReadBlock(pbXcursor, pbYcursor, 0, pb);
                System.Array safeArray;
                // Put the pixel block into a SafeArray for manipulation.
                safeArray=(System.Array)pb.get_SafeArray(0);

                // Iterate through the pixels in the pixel block.
                for (int safeArrayHeight=0; safeArrayHeight < pb.Height;
                    safeArrayHeight++)
                {
                    for (int safeArrayWidth=0; safeArrayWidth < pb.Width;
                        safeArrayWidth++)
                    {
                        // Use System.Array.SetValue to write the new pixel value back into the SafeArray.
                        safeArray.SetValue(Convert.ToByte(128), safeArrayWidth,
                            safeArrayHeight);
                    }
                }
                // Set the SafeArray back to the pixel block.
                pb.set_SafeArray(0, safeArray);

                // Write the pixel block back to the dataset.
                rawBlocks.WriteBlock(pbXcursor, pbYcursor, 0, pb);
            }
        }
    }
}
[VB.NET]
Public Sub ReadWriteRawBlocks(ByVal rasDs As IRasterDataset)
    Dim rasBandCol As IRasterBandCollection
    rasBandCol=rasDs
    Dim rawBlocks As IRawBlocks
    Dim rasInfo As IRasterInfo
    Dim pb As IPixelBlock
    ' Iterate through each band of the dataset.
    For m=0 To rasBandCol.Count - 1
        ' QI to IRawBlocks from IRasterBandCollection.
        rawBlocks=rasBandCol.Item(m)
        rasInfo=rawBlocks.RasterInfo
        ' Create the pixel block.
        pb=rawBlocks.CreatePixelBlock
        ' Determine the tiling scheme for the raster dataset.
        Dim startX, startY, endX, endY As Integer
        
        Dim bStartX As Integer=CInt(Math.Floor((rasInfo.Extent.Envelope.XMin - rasInfo.Origin.X) / _
                                 (rasInfo.BlockWidth * rasInfo.CellSize.X)))
        Dim bEndX As Integer=CInt(Math.Ceiling((rasInfo.Extent.Envelope.XMax - rasInfo.Origin.X) / _
                               (rasInfo.BlockWidth * rasInfo.CellSize.X)))
        Dim bStartY As Integer=CInt(Math.Floor((rasInfo.Origin.Y - rasInfo.Extent.Envelope.YMax) / _
                                 (rasInfo.BlockHeight * rasInfo.CellSize.Y)))
        Dim bEndY As Integer=CInt(Math.Ceiling((rasInfo.Origin.Y - rasInfo.Extent.Envelope.YMin) / _
                               (rasInfo.BlockHeight * rasInfo.CellSize.Y)))
        
        ' Iterate through the pixel blocks.
        For pbYcursor=startY To endY - 1
            For pbXcursor=startX To endX - 1
                ' Get the pixel block.
                rawBlocks.ReadBlock(pbXcursor, pbYcursor, 0, pb)
                Dim safeArray As System.Array
                ' Put the pixel block into a SafeArray for manipulation.
                safeArray=pb.SafeArray(0)
                ' Iterate through the pixels in the pixel block.
                For safeArrayHeight=0 To pb.Height
                    For safeArrayWidth=0 To pb.Width
                        ' Use System.Array.SetValue to write the new pixel value (128) back into the SafeArray.
                        safeArray.SetValue(CType(128, Byte), safeArrayWidth, safeArrayHeight)
                    Next
                Next
                ' Set the SafeArray back to the pixel block.
                pb.SafeArray(0)=safeArray
                ' Write the pixel block back to the dataset.
                rawBlocks.WriteBlock(pbXcursor, pbYcursor, 0, pb)
            Next
        Next
    Next
End Sub


See Also:

How to access pixel data using a raster cursor




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS Desktop Basic ArcGIS Desktop Basic
ArcGIS Desktop Standard ArcGIS Desktop Standard
ArcGIS Desktop Advanced ArcGIS Desktop Advanced
Engine Developer Kit Engine