@mapbox/geo-pixel-stream

0.5.0 • Public • Published

geo-pixel-stream

Build Status

[wip] Node.js streams for reading/writing/transforming pixels using node-gdal

PixelReader streams

Create streams that read pixels from each band of a source image:

var pixels = require('@mapbox/geo-pixel-stream');
var dcrgb = 'node_modules/mapnik-test-data/data/geotiff/DC_rgb.tif';
var readers = pixels.createReadStreams(dcrgb);

If an image has 4 bands (e.g. RGBA), then the streams array will contain four stream objects. Each stream contains metadata about the original datasource and the band represented:

console.log(readers[0].metadata);
// {
//   driver: 'GTiff',
//   width: 1541,
//   height: 1913,
//   numBands: 4,
//   srs: gdal.SpatialReference.fromEPSG(26918),
//   geotransform: [ 326356, 4.00129785853342, 0, 4318980, 0, -4.0015682174594875 ],
//   id: 1,
//   type: 'Byte',
//   blockSize: {
//     x: 1541,
//     y: 1
//   }
// }

Each PixelReader is a Node.js readable stream. The stream's data event will emit objects indicating the offset (in terms of blocks, not pixels), block size (in pixels) and a TypedArray of pixel data.

readers[0].once('data', function(data) {
  console.log(data);
  // {
  //   offset: { x: 0, y: 0 },
  //   blockSize: { x: 1541, y: 1 },
  //   buffer: [ Uint8TypedArray ]
  // }
});

Inheriting from the stream api, PixelReaders can send data to writable streams via pipe:

var writable = new stream.Writable();
readers[1].pipe(writable);

PixelWriter streams

Create streams that write pixels from each band of a destination image:

var outputFile = '~/some.tif';
var writers = pixels.createWriteStreams(outputFile);

Again, if this will generate one stream for each band of the output file. If, instead of writing to an existing file, you want to write to a new, blank image, you must provide sufficient metadata to generate the new image:

var outfile = '~/just-red-pixels.tif'
var outputMetadata = {
  driver: 'GTiff',
  width: 1541,
  height: 1913,
  numBands: 1,
  srs: gdal.SpatialReference.fromEPSG(26918),
  geotransform: [ 326356, 4.00129785853342, 0, 4318980, 0, -4.0015682174594875 ],
  id: 1,
  type: 'Byte',
  blockSize: { x: 1541, y: 1 }
};
var writers = pixels.createWriteStreams(outputFile, outputMetadata);

Once you've created readers and writers, you can pipe data from one image to another:

var dcrgb = 'node_modules/mapnik-test-data/data/geotiff/DC_rgb.tif';
var readers = pixels.createReadStreams(dcrgb);
var readRedBand = readers[0];

var writers = pixels.createWriteStreams(outputFile);
var writeRedBand = writers[0];

readRedBand.pipe(writeRedBand).on('finish', function() {
  console.log('All done!');
});

PixelTransform streams

Create a stream that takes input pixels, performs some sort of manipulation of them, and outputs the adjusted pixels. You create a function that will receive a TypedArray of pixels, performs some adjustment, and provides the adjusted pixels to the provided callback function:

function processPixels(buffer, callback) {
  var result = buffer.map(function(pixel) {
    return pixel + 10;
  });
  callback(null, result);
}

var transform = pixels.createTransformStream(processPixels);

If processing encounters an error, send the error as the first argument to the provided callback function.

You can use a transform stream to make adjustments to pixel values before writing them to a destination file:

var dcrgb = 'node_modules/mapnik-test-data/data/geotiff/DC_rgb.tif';
var readers = pixels.createReadStreams(dcrgb);
var writers = pixels.createWriteStreams(outputFile);
var transform = pixels.createTransformStream(processPixels);

readers[0].pipe(transform).pipe(writers[0]).on('close', function() {
  console.log('All done!');
});

Readme

Keywords

none

Package Sidebar

Install

npm i @mapbox/geo-pixel-stream

Weekly Downloads

6

Version

0.5.0

License

ISC

Last publish

Collaborators

  • mbx-npm-ci-production
  • mbx-npm-ci-staging
  • mbx-npm-advanced-actions-production
  • mbx-npm-advanced-actions-staging
  • mbx-npm-09-production
  • mbx-npm-08-production
  • mbx-npm-07-production
  • mbx-npm-06-production
  • mbx-npm-05-production
  • mbx-npm-04-production
  • mbx-npm-03-production
  • mbx-npm-02-production
  • mbx-npm-01-production
  • mbx-npm-02-staging
  • mapbox-npm-01
  • mapbox-npm-02
  • mapbox-npm-07
  • mapbox-npm-03
  • mapbox-npm-04
  • mapbox-npm-09
  • mapbox-npm-05
  • mapbox-npm-06
  • mapbox-npm-08
  • mapbox-npm-advanced-actions
  • mapbox-npm-ci
  • mapbox-npm
  • mapbox-admin
  • mapbox-machine-user