First Look at a Raster File: Dimensions, Bands, and NoData

tool
raster
bilingual
Upload a GeoTIFF and get an instant summary — dimensions, resolution, band count, CRS, NoData, and per-band min/max/mean — in Python and R on the same map.
Published

September 6, 2026

A vector file’s first look answers “how many features, what shape, what CRS.” A raster’s is a different set of numbers entirely: how big is the grid, how many bands does each pixel carry, what does one pixel cover on the ground, and which value means “no data here” rather than a real measurement.

Get those wrong and everything downstream is wrong too — a slope calculation that treats -9999 as a very steep cliff, a mean elevation dragged down by a border of NoData pixels, a band mistaken for degrees Celsius when it’s really reflectance times 10,000.

Just want the summary, without the rest of the reading? Use the standalone tool — same engine, less prose.

1. Upload your file

A single .tif or .tiff — no sidecars, unlike a shapefile.

2. Why start with a summary?

Eight numbers, each answering a question that’s otherwise easy to get wrong by assumption:

  • Dimensions — width × height in pixels. Determines how much work any pixel-by-pixel operation actually is, and whether a “small” file is small in bytes but enormous in pixel count (or the reverse).
  • Bands — one grid of numbers, or several stacked together (RGB, a multispectral stack, a time series). Some checks and most visualizations only make sense once you know how many there are.
  • CRS — same coordinate reference system concept as a vector file, same convention here: a missing CRS is assumed WGS84 and flagged, never silently treated as CRS-less.
  • Resolution — the ground distance one pixel actually covers, in the file’s own CRS units. A 30 (Landsat-scale) versus a 0.001 (sub-meter) changes what questions the data can even answer.
  • Data typeuint8, int16, float32, … . The single most common source of a “why are all my values 0 or wildly wrong” surprise: an integer type storing values that were meant to be divided by a scale factor, or a float column silently truncated by being written back as an integer type.
  • NoData — the sentinel value marking “no measurement here” (often -9999, 0, or a type’s max value) — as fundamental to a raster as a null is to a table column, and just as easy to accidentally treat as a real number if it isn’t checked first.
  • Bounds — the same bounding-box sanity check as a vector file: numbers wildly outside -180..180 / -90..90 are the CRS-mismatch tell, here too.
  • Value range — the per-band min/max/mean, with NoData pixels correctly excluded. The fastest way to catch a unit mistake (a “temperature in Celsius” band whose values run from 200 to 320 is actually Kelvin) before it reaches an analysis.

3. Shared map and summary

4. Inspect: summarize your file

Run the same summary in Python or R on the current data (your file uploaded above, or the built-in example below).

5. Same spatial question, two languages

Python and R read the same file through the same underlying GDAL, but the two engines disagree in ways a vector file’s sf/GeoPandas split never surfaces:

Python (rasterio)

src.width, src.height     # dimensions
src.count                 # band count
src.crs                   # CRS
src.res                   # pixel resolution
src.dtypes[0]              # data type, as declared in the file
src.nodata                 # the NoData sentinel value itself
src.read(i, masked=True)  # one band, NoData pixels masked out

R (stars)

st_dimensions(r)          # dimensions + band count
sf::st_crs(r)$input       # CRS
st_dimensions(r)$x$delta  # pixel resolution
typeof(r[[1]])            # R's storage type, not the file's declared type
# no direct equivalent — see below
r[[1]]                    # already has NoData pixels as NA

Three genuine divergences, not just naming differences:

  • CRS formatting — same issue as the vector article’s st_crs() vs GeoPandas footnote: st_crs(r)$input and str(src.crs) don’t always print the same string for the same underlying CRS.1
  • Data typestars always stores pixel values as R doubles internally; it doesn’t expose the file’s own declared GDAL type (uint8, int16, float32, …) the way rasterio’s dtypes[0] does. The R summary above reports "double" for every raster, regardless of what’s actually on disk — a real limitation, not a rounding choice.
  • NoData retentionread_stars() converts a file’s declared NoData value to NA automatically at read time (confirmed: a -9999 sentinel pixel never pollutes min()/max() above), but it doesn’t keep the sentinel value itself accessible anywhere afterwards. rasterio does the opposite: masked=True excludes NoData pixels from a calculation, but src.nodata still tells you the raw number the file uses. That’s why the R card’s “NoData” row never shows anything but “None declared,” even on a file that clearly has one — it isn’t wrong, stars genuinely doesn’t retain it this way.

1 A GeoTIFF’s own embedded CRS often resolves to a human-readable name in GDAL’s metadata (e.g. "WGS 84"), which R’s st_crs()$input reports directly — while an EPSG code assigned explicitly in code (as the built-in example above does) round-trips back as "EPSG:4326" on both sides. Worth checking which one you’re looking at before assuming a mismatch means an actual problem.

6. A raster with no declared CRS

The reusable cell pair above already builds a small synthetic hill with one NoData pixel whenever nothing has been uploaded — click ▶ Run on both languages in section 4 to see it. This button swaps in the same raster, minus the CRS, to see the warning row do its job.2

2 An unreferenced raster isn’t rare in practice — a sensor’s raw output, or a file exported by a tool that never wrote a CRS tag at all. Nothing about the pixel values is wrong in that case; only where they sit on the earth is unknown until someone supplies it, which is exactly the situation the warning exists to flag before a map silently plots it in the wrong place (or, for sf/GeoPandas, refuses to reproject it at all).

7. Where to next

A summary is a starting point:

  • Just needed the numbers? The standalone Raster Inspector has the same summary, no reading required.
  • Working with vector data instead? Start with First Look at a Geospatial File — the same idea, for GeoJSON and Shapefile.
  • Need to combine or transform bands (an NDVI-style calculation, a reclassification)? A Calculator/Band Math tool is planned as the next tool in the Raster family.