如何配置GridCoverageWriter将波段数据类型设为byte而非float16?
如何将GridCoverage2D存储为Byte类型的TIFF文件?
当然可以实现这个需求,核心需要两步:将原始GridCoverage2D的float16数据转换为byte类型,同时指定GeoTIFF写入参数的像素类型为byte。
关键修改点
- 先对原始栅格数据做类型转换,把float16数值映射到byte的0-255范围(如果原始数据范围不是这个区间,需要先做归一化/缩放)
- 在
GeoTiffWriteParams中显式设置像素类型为byte
修改后的完整代码
import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageProcessor; import org.geotools.gce.geotiff.GeoTiffFormat; import org.geotools.gce.geotiff.GeoTiffWriteParams; import org.geotools.parameter.ParameterValueGroup; import org.opengis.parameter.GeneralParameterValue; import org.opengis.referencing.operation.MathTransform; import java.io.File; // ... 你的其他业务代码 final GeoTiffFormat format2 = new GeoTiffFormat(); final GeoTiffWriteParams wp = new GeoTiffWriteParams(); wp.setCompressionMode(GeoTiffWriteParams.MODE_EXPLICIT); wp.setCompressionType("LZW"); // 关键配置:指定输出像素类型为byte wp.setPixelType(GeoTiffWriteParams.PIXEL_TYPE_BYTE); // 注意这里要使用实例化的format2获取写入参数,原代码的format是错误的 final ParameterValueGroup params = format2.getWriteParameters(); params.parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()).setValue(wp); GridCoverageWriter writer = null; if (grdCov != null) { // 第一步:将float16类型的栅格转换为byte类型 GridCoverageProcessor processor = new GridCoverageProcessor(); // 获取原始数据的数值范围,根据实际情况调整 double minValue = grdCov.getSampleDimension(0).getMinimumValue(); double maxValue = grdCov.getSampleDimension(0).getMaximumValue(); // 构建缩放变换,把原始数据映射到0-255区间 double scale = 255 / (maxValue - minValue); MathTransform scaleTransform = org.geotools.referencing.operation.transform.AffineTransform2D.getScaleInstance(scale, scale); MathTransform offsetTransform = org.geotools.referencing.operation.transform.AffineTransform2D.getTranslateInstance(-minValue * scale, -minValue * scale); MathTransform finalTransform = org.geotools.referencing.operation.transform.ConcatenatedTransform.create(scaleTransform, offsetTransform); GridCoverage2D byteCoverage = (GridCoverage2D) processor.resample(grdCov, finalTransform, byte.class); final File writeFile = new File(txtOutputName.getText()); writer = format2.getWriter(writeFile); // 写入转换后的byte类型栅格数据 writer.write(byteCoverage, (GeneralParameterValue[]) params.values().toArray(new GeneralParameterValue[params.values().size()])); } // 确保资源释放 if (writer != null) { writer.dispose(); }
注意事项
- 数据缩放逻辑必须匹配你原始float16数据的实际数值范围,如果原始数据已经是0-255的浮点值,可以直接跳过缩放,直接转换类型
- 原代码中
format.getWriteParameters()是错误的,必须使用你实例化的format2对象获取参数 - 必须先完成数据类型转换再写入,否则即使设置了
PixelType,也会因原始数据类型不匹配报错
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

