I'm writing a simple utility to crop batches of multi-band geotiff raster files to the same (smaller) area. Using gdalwarp, I can easily crop a file using a single-polygon clipping shapefile:

gdalwarp -cutline clipper.shp -crop_to_cutline input.tif output.tif

However, the actual area I want to clip to will always be initially defined by another geotiff raster file, not a shapefile. It would be nice if I could use the extent of that raster as the clipping file, but I'm not sure how to do this. Unsurprisingly, the following doesn't work (it doesn't raise an error, it just doesn't produce anything):

gdalwarp -cutline clipper.tif-crop_to_cutline input.tif output.tif

So, my question is, is there a way to supply a raster to gdalwarp -cutline? Alternately, is there another gdal function that can clip a raster using another raster? If neither of these are possible, is there a very simple way to produce a shapefile with a single polygon defined by the extent of a raster?

This code will be wrapped in a more extensive python script, so I can use either command line gdal utilities or any of the python bindings for gdal.

As a side note, I know that I could easily just make a clipping shapefile that covers the extent of my raster in QGIS. I may wind up doing that if I don't find a straightforward solution, but I will ultimately wind up using this utility on dozens if not hundreds of areas as part of a large automated analysis, so I'd prefer not to have a tedious manual step even if it is very easy.

  • This solution only works if they are in the same SRS. Works fine for me. U Can try put "MEM" in the output and list bands from a stack. – Fronza Apr 7 at 14:51

I don't know if it's possible to clip a raster with an other raster but you could use gdaltindex to build the shapefile with the extent of your raster.


| improve this answer | |
  • 4
    gdaltindex works perfectly to make a clipping shapefile from my initial raster. To solve the problem I use gdaltindex clipper.shp clipper.tif, followed by gdalwarp -cutline clipper.shp -crop_to_cutline input.tif output.tif – Joe Dec 12 '14 at 17:03
  • I was using this approach but found that it sometimes was a single pixel off in the clipped version. I think it's more straightforward to compute your target extents a la Xavier's answer below and then use gdalwarp and specify -te_srs to handle mismatched CRSs. – Jon Dec 18 '19 at 5:22

For irregular polygons, and assuming that your geotiff raster file is a binary raster, you could use GDAL_Calc:

GDAL_Calc.py -A Mask.tif -B CutBigImageToClip.tif --outfile=SmallerFile.tif --NoDataValue=0 --Calc="B*(A>0)" 

This query will populate 0 where Mask.tif <= 0 and BigImage where the Mask > 0. To do this both rasters must be the same cell size, rows and columns. To extract the same extents use GDAL_Translate with the -projwin ulx uly lrx lry option (box is in projected coordinates), but ensure that the projwin box does not extend over the edges of either raster.

GDAL_Translate -of GTIFF -projwin ulx uly lrx lry BigImageToClip.tif CutBigImageToClip.tif

Substitute values for the projwin box derived from the Mask.

| improve this answer | |
  • 1
    +1 This is useful information, but I think I can solve my problem in fewer steps using @lejedi's answer. – Joe Dec 12 '14 at 17:00

The solution in Python directly, without making shape:

import gdal
from gdalconst import GA_ReadOnly

data = gdal.Open('img_mask.tif', GA_ReadOnly)
geoTransform = data.GetGeoTransform()
minx = geoTransform[0]
maxy = geoTransform[3]
maxx = minx + geoTransform[1] * data.RasterXSize
miny = maxy + geoTransform[5] * data.RasterYSize
call('gdal_translate -projwin ' + ' '.join([str(x) for x in [minx, maxy, maxx, miny]]) + ' -of GTiff img_orig.tif img_out.tif', shell=True)
| improve this answer | |
  • 1
    NB: This solution only works if they are in the same SRS. – Skylion Nov 16 '16 at 18:10
  • @Skylion But you can easily account for this by including the -te_srs option, although you also need to gdalwarp instead with the -te option. – Jon Dec 18 '19 at 5:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.