How to set raster properties when saving as a raster


Summary
This topic shows how to set raster properties (such as cell size, extent, and NoData value) on a raster before saving.
To clip a portion of a raster dataset programmatically, use the Clip geoprocessing command.


Setting raster properties when saving as a raster

The ISaveAs interface works with both raster datasets and rasters. If used on a raster dataset, the Save as function basically performs a format conversion. If used on a raster, the property of the raster can be modified.
To set a raster with a specific cell size, the row and column must be adjusted. To accomplish this, follow these steps:
  1. Start with an IRaster object to modify and a new cell size and extent to apply.
  2. Calculate the new image size (col, row) based on the extent and cell size.
  3. Refine the extent envelope based on the new lower left corner pixel size and image size.  This will ensure the pixel sizes (which are not stored explicitly) can be recreated from the extent and image size.
  4. Cast to get an IRasterProps interface (rasterProps) into the IRaster object.
  5. Use rasterProps to set the new extent and image size.
  6. Cast to get an ISaveAs interface (saveAs) based on rasterProps.
  7. Use the SaveAs method to save the file as an IMAGINE Image file.
See the following code
[C#]
public static void SetCellSizeAndExtentOnRaster(double cellSize, IEnvelope extent,
    IRaster raster)
{
    //Clip a raster or transform a raster; the cell size will be changed. To set a specified cell 
    //size for the output, you need to adjust the extent, row, and column accordingly.

    //The cellSize is the output cell size of the raster.
    //The extent is the output extent of the raster.
    //The raster is the input raster.

    //Calculate the height and width of the output raster.
    int col = Convert.ToInt16((extent.XMax - extent.XMin) / cellSize);
    int row = Convert.ToInt16((extent.YMax - extent.YMin) / cellSize);

    //Adjust the extent.
    IPoint lowerLeft = extent.LowerLeft;
    IPoint UpperRight = new PointClass();
    IEnvelope newExtent = new EnvelopeClass();
    UpperRight.X = lowerLeft.X + col * cellSize;
    UpperRight.Y = lowerLeft.Y + row * cellSize;
    newExtent.LowerLeft = lowerLeft;
    newExtent.UpperRight = UpperRight;

    //Then put the extent, height, and width.
    IRasterProps rasterProps = (IRasterProps)raster;
    rasterProps.Extent = newExtent;
    rasterProps.Height = row;
    rasterProps.Width = col;

    //Save it.
    ISaveAs saveAs = rasterProps as ISaveAs;
    saveAs.SaveAs(@"c:\temp\image1.img", null, "IMAGINE Image");
}
[VB.NET]
Public Sub SetCellSizeAndExtentOnRaster(ByVal cellSize As Double, ByVal extent As IEnvelope, ByVal raster As IRaster)
    
    'Clip a raster or transform a raster; the cell size will be changed. To set a specified cell
    'size for the output, you need to adjust the extent, row, and column accordingly.
    
    'The cellSize is the output cell size of the raster.
    'The extent is the output extent of the raster.
    'The raster is the input raster.
    
    'Calculate the height and width of the output raster.
    Dim col As Integer = Convert.ToInt16((extent.XMax - extent.XMin) / cellSize)
    Dim row As Integer = Convert.ToInt16((extent.YMax - extent.YMin) / cellSize)
    
    'Adjust the extent.
    Dim lowerLeft As IPoint = extent.LowerLeft
    Dim UpperRight As IPoint = New PointClass()
    Dim newExtent As IEnvelope = New EnvelopeClass()
    UpperRight.X = lowerLeft.X + col * cellSize
    UpperRight.Y = lowerLeft.Y + row * cellSize
    newExtent.LowerLeft = lowerLeft
    newExtent.UpperRight = UpperRight
    
    'Then put the extent, height, and width.
    Dim rasterProps As IRasterProps = CType(raster, IRasterProps)
    rasterProps.Extent = newExtent
    rasterProps.Height = row
    rasterProps.Width = col
    
    'Save it.
    Dim saveAs As ISaveAs = TryCast(rasterProps, ISaveAs)
    saveAs.SaveAs("c:\temp\image1.img", Nothing, "IMAGINE Image")
    
End Sub

Setting a NoData value

To set a NoData value on a raster, follow these steps:
  1. Start with an IRaster object (raster).
  2. Cast to get an IRasterProps interface (rasterProps) into the IRaster object.
  3. Set the NoDataValue property, depending on the number of bands:
    1. If there are three bands (and the values differ), set three values.
    2. Otherwise, set one value.
  4. Use the ISave interface to save the file in the desired format.
See the following code:
[C#]
public static void SetNoDataSaveAs(IRaster raster, IWorkspace ws, string sFormat,
    string sName)
{
    IRasterProps rasterProps = (IRasterProps)raster;
    IRasterBandCollection bandCol = (IRasterBandCollection)raster;
    int nBandCount = bandCol.Count;
    if (nBandCount == 3)
    {
        //For a multiband image, set a NoData value for each band if they're not the same.
        int[] nodata = 
        {
            255, 255, 236
        };
        rasterProps.NoDataValue = nodata;
    }
    else
    {
        // If the raster has one band or if the NoData values for each band are the same, 
        // specify only one value.
        rasterProps.NoDataValue = 255;
    }

    ISaveAs saveas = raster as ISaveAs;
    saveas.SaveAs(sName, ws, sFormat);
    return ;
}
[VB.NET]
Public Sub SetNoDataSaveAs(ByVal raster As IRaster, ByVal ws As IWorkspace, ByVal sFormat As String, ByVal sName As String)
    Dim rasterProps As IRasterProps = CType(raster, IRasterProps)
    Dim rasterBandCol As IRasterBandCollection = CType(raster, IRasterBandCollection)
    Dim nBands As Integer = rasterBandCol.Count()
    If nBands = 3 Then
        'For a multiband image, set a NoData value for each band if they're not the same.
        Dim nodata As Integer() = {255, 255, 236}
        rasterProps.NoDataValue = nodata
    Else
        'For one band rasters or if the NoData values for each band are the same,
        'specify only one value.
        rasterProps.NoDataValue = 255
    End If
    
    Dim saveas As ISaveAs = TryCast(raster, ISaveAs)
    saveas.SaveAs(sName, ws, sFormat)
    Return
End Sub


See Also:

How to clip a raster dataset with an envelope or a dataset




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 for Desktop Basic ArcGIS for Desktop Basic
ArcGIS for Desktop Standard ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced ArcGIS for Desktop Advanced
Engine Developer Kit Engine