geotiffjs / geotiff.js

geotiff.js is a small library to parse TIFF files for visualization or analysis. It is written in pure JavaScript, and is usable in both the browser and node.js applications.
https://geotiffjs.github.io/
MIT License
855 stars 176 forks source link

Writing to file #294

Open LeopardTree opened 2 years ago

LeopardTree commented 2 years ago

I want to write a geotiff file from a file I've read with geotiff.js. According to the website are the writeArrayBuffer() method in Beta version so I know it's not so reliable, but I want to know if it's possible creating a geotiff file with it?

The .tif files I'll managed to create can't be opened in normal picture programs, only in qgis. The values get right for rasters with integer values. But for rasters with floating values the values get truncated. Tries to increase BitsPerSample to 32 but didn't work.

If someone knows how to do it would be great.

Here's the code for a greyscale image:

const tif = await fromFile('birch.tif'); 
const image = await tif.getImage();
console.log(image);
const layer = await image.readRasters();
const raster = layer[0];
const values = `raster;`

for(let i = 0; i < values.length; i++){
  values[i] = values[i]*100;
}
const imageHeight = await layer.height;
const imageWidth = await layer.width;
const geoKeys = await tif.geoKeys;
let fileDir = await image.getFileDirectory();
const stripOffsets = await image.fileDirectory.StripOffsets;
const stripByteCounts = await image.fileDirectory.StripByteCounts;
let XResolution = await fileDir.XResolution;
let YResolution = await 
fileDir.YResolution;

if(!XResolution){
  XResolution = [1, 1];
}
if(!YResolution){
  YResolution = [1, 1];
}
const ModelPixelScale = await fileDir.ModelPixelScale;
const ModelTiepoint = await fileDir.ModelTiepoint; 
const GeoKeyDirectory = await image.fileDirectory.GeoKeyDirectory;
const BitsPerSample = await fileDir.BitsPerSample;
const GeoAsciiParams = await fileDir.GeoAsciiParams;
const PhotometricInterpretation = await fileDir.PhotometricInterpretation;
const Compression = await fileDir.Compression;
const SamplesPerPixel = await fileDir.SamplesPerPixel;
const Orientation = 1;
const ProjectedCSTypeGeoKey = await image.geoKeys.ProjectedCSTypeGeoKey;

const metadata = {
height: imageHeight,
width: imageWidth,
StripOffsets: stripOffsets,
StripByteCounts: stripByteCounts,
XResolution: XResolution,
YResolution: YResolution,
ModelPixelScale: ModelPixelScale,
ModelTiepoint: ModelTiepoint,
GeoKeyDirectory: GeoKeyDirectory,
GeoAsciiParams: GeoAsciiParams,
PhotometricInterpretation: PhotometricInterpretation,
Compression: Compression,
SamplesPerPixel: SamplesPerPixel,
ProjectedCSTypeGeoKey: ProjectedCSTypeGeoKey,
DateTime: '',
Orientation: Orientation}

const arrayBuffer = await writeArrayBuffer(raster, metadata);
const tif2 = await fromArrayBuffer(arrayBuffer);
const image2 = await tif2.getImage();
console.log(image2);

const buffer = Buffer.from(arrayBuffer);
let writeStream = fs.createWriteStream('birch_copyX5.tif');
writeStream.write(buffer, 'utf8');
writeStream.on('finish', () => {
  console.log('wrote all data to file');
});
// close the stream
writeStream.end();

FileDirectory before WriteArrayBuffer:

image

FileDirectory after WriteArrayBuffer:

image

DanielJDufour commented 2 years ago

👋 @LeopardTree . Hello. Sorry for the late reply. I authored the GeoTIFF writer and happy to help debug.

DanielJDufour commented 2 years ago

I ran into this issue as well working on another project. I think the main issue is this line: https://github.com/geotiffjs/geotiff.js/blob/master/src/geotiffwriter.js#L255, which assumes that your data is in 8-bit 0-255 integer range. Just confirming the limitation. It'll require some refactoring. I'll be able to do it, but I'm unlikely to find time till mid-september after FOSS4G at the earliest.

LeopardTree commented 2 years ago

Hey.

Thx for the help. I've changed workplace now so it's not so relevant anymore. We used the library gdal-async instead to solve it.

Ty

Ludvig

Den lör 9 juli 2022 22:44Daniel J. Dufour @.***> skrev:

I ran into this issue as well working on another project. I think the main issue is this line: https://github.com/geotiffjs/geotiff.js/blob/master/src/geotiffwriter.js#L255, which assumes that your data is in 8-bit 0-255 integer range. Just confirming the limitation. It'll require some refactoring. I'll be able to do it, but I'm unlikely to find time till mid-september after FOSS4G at the earliest.

— Reply to this email directly, view it on GitHub https://github.com/geotiffjs/geotiff.js/issues/294#issuecomment-1179604177, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARIUPDQGWI4LMUPZX5JTHWTVTHQELANCNFSM5RQQ6M4A . You are receiving this because you were mentioned.Message ID: @.***>

manivannan23k commented 2 years ago

Facing the same issue while trying to write float values into tif file.