3

I've got a lot of image files (.png or .jpg) that I want to convert from one EPSG defined CRS system to another, e.g. from EPSG:31255 to EPSG:25833, on a server within a Java app.

For each image I know the coordinates (x,y) of the lower left and upper right corner in that specific CRS system.

What I've found so far:

  • QGIS: Is able to do this but I'd have to do it by hand (answer)
  • GDAL: Is able to convert images but it uses C++ (which I can't use on the server)
  • Proj4js: Can only convert coordinates
  • Geotools: I've only found information about converting coordinates or full shapefiles so far.

Can GeoTools convert images too or what other Java/JavaScript library can?

Edit:

I'm currently using version 22.2 of GeoTools. The dependencies in the pom.xml file are:

  • junit
  • gt-shapefile
  • gt-swing
  • gt-geotiff
  • gt-image (not sure if I need that one)
  • gt-epsg-hsql

The imports in the java file are:

  • import org.geotools.coverage.grid.GridCoverage2D;
  • import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
  • import org.geotools.coverage.grid.io.AbstractGridFormat;
  • import org.geotools.coverage.grid.io.GridFormatFinder;
  • import org.geotools.coverage.processing.Operations;
  • import org.geotools.gce.geotiff.GeoTiffFormat;
  • import org.geotools.gce.geotiff.GeoTiffWriter;
  • import org.geotools.referencing.CRS;
  • import org.geotools.util.factory.Hints;
  • import org.opengis.referencing.crs.CoordinateReferenceSystem;
Neph
  • 235
  • 1
  • 9

2 Answers2

3

If you have a matching .wld and .prj file then the gt-image module can read and write jpeg and png files.

Once you've read the file in to a GridCoverage you can reproject it and write it out with no difficulty:

AbstractGridFormat format = GridFormatFinder.findFormat(input);
Hints hints = null;
if (format instanceof GeoTiffFormat) {
  hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
}

AbstractGridCoverage2DReader reader = format.getReader(input, hints);
GridCoverage2D coverage = reader.read(null);
reader.dispose();
GridCoverage2D coverageTransf = (GridCoverage2D) Operations.DEFAULT.resample(coverage, targetCRS);

GeoTiffFormat outFormat = new GeoTiffFormat();
GridCoverageWriter writer = outFormat.getWriter(destFile, hints);
writer.write(coverageTransf, null);
writer.dispose();

Assuming your input image is in input, your target CRS is in targetCRS and the output file is in destFile.

PS: see my blog post on how to add a .prj file to a lot of world images if they are missing.

Ian Turton
  • 81,417
  • 6
  • 84
  • 185
0

Some additional information:

To get the code in Ian Turton's answer (GeoTools 22.2, Java 8) to run properly I had to add the following dependencies to the pom.xml file:

<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-geotiff</artifactId>
    <version>${geotools.version}</version>
</dependency>
<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-image</artifactId>
    <version>${geotools.version}</version>
</dependency>
<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-epsg-hsql</artifactId>
    <version>${geotools.version}</version>
</dependency>

Why?:

  • gt-geotiff: Used for GeoTiffFormat (Error: GeoTiffFormat cannot be resolved to a type)
  • gt-image: Without you'll get Trying to get a reader from an unknown format. with AbstractGridCoverage2DReader reader = format.getReader(input, hints)
  • gt-epsg-hsql: Otherwise you'll get: org.opengis.referencing.NoSuchAuthorityCodeException: No code "EPSG:25833" from authority "EPSG" found for object of type "EngineeringCRS".
  • I also added gt-coverage at first but the app seems to run fine without it.

I also had to get rid of the Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER hint, otherwise the output images would all be mirrored and rotated by 90°. This does seem to depend on the used .prj file:

The file (for "EPSG:31255") I downloaded from epsg.io (use the "Well Known Text as HTML" export and rename!) works fine as it includes "TOWGS84". The .prj file I got from spatialreference.org also includes that code but still produces a wrong result (didn't test their "WKT as HTML" version though).

Neph
  • 235
  • 1
  • 9