Add support for auto conversion to RGB

This commit is contained in:
Tim Schaub
2022-08-28 11:38:35 -05:00
parent c742fe965f
commit bd3b1bb434
6 changed files with 98 additions and 10 deletions

View File

@@ -5,6 +5,7 @@ import DataTile from './DataTile.js';
import TileGrid from '../tilegrid/TileGrid.js';
import {
Pool,
globals as geotiffGlobals,
fromBlob as tiffFromBlob,
fromUrl as tiffFromUrl,
fromUrls as tiffFromUrls,
@@ -31,6 +32,31 @@ function isMask(image) {
return (type & 4) === 4;
}
/**
* @param {true|false|'auto'} preference The convertToRGB option.
* @param {GeoTIFFImage} image The image.
* @return {boolean} Use the `image.readRGB()` method.
*/
function readRGB(preference, image) {
if (!preference) {
return false;
}
if (preference === true) {
return true;
}
if (image.getSamplesPerPixel() !== 3) {
return false;
}
const interpretation = image.fileDirectory.PhotometricInterpretation;
const interpretations = geotiffGlobals.photometricInterpretations;
return (
interpretation === interpretations.CMYK ||
interpretation === interpretations.YCbCr ||
interpretation === interpretations.CIELab ||
interpretation === interpretations.ICCLab
);
}
/**
* @typedef {Object} SourceInfo
* @property {string} [url] URL for the source GeoTIFF.
@@ -320,9 +346,10 @@ function getMaxForDataType(array) {
* another with 1 band, the resulting data tiles will have 5 bands: 3 from the first source, 1 alpha
* band from the first source, and 1 band from the second source.
* @property {GeoTIFFSourceOptions} [sourceOptions] Additional options to be passed to [geotiff.js](https://geotiffjs.github.io/geotiff.js/module-geotiff.html)'s `fromUrl` or `fromUrls` methods.
* @property {boolean} [convertToRGB = false] By default, bands from the sources are read as-is. When
* @property {true|false|'auto'} [convertToRGB=false] By default, bands from the sources are read as-is. When
* reading GeoTIFFs with the purpose of displaying them as RGB images, setting this to `true` will
* convert other color spaces (YCbCr, CMYK) to RGB.
* convert other color spaces (YCbCr, CMYK) to RGB. Setting the option to `'auto'` will make it so CMYK, YCbCr,
* CIELab, and ICCLab images will automatically be converted to RGB.
* @property {boolean} [normalize=true] By default, the source data is normalized to values between
* 0 and 1 with scaling factors based on the raster statistics or `min` and `max` properties of each source.
* If instead you want to work with the raw values in a style expression, set this to `false`. Setting this option
@@ -424,9 +451,9 @@ class GeoTIFFSource extends DataTile {
this.error_ = null;
/**
* @type {'readRasters' | 'readRGB'}
* @type {true|false|'auto'}
*/
this.readMethod_ = options.convertToRGB ? 'readRGB' : 'readRasters';
this.convertToRGB_ = options.convertToRGB || false;
this.setKey(this.sourceInfo_.map((source) => source.url).join(','));
@@ -747,7 +774,7 @@ class GeoTIFFSource extends DataTile {
}
}
requests[sourceIndex] = image[this.readMethod_]({
const readOptions = {
window: pixelBounds,
width: sourceTileSize[0],
height: sourceTileSize[1],
@@ -755,7 +782,12 @@ class GeoTIFFSource extends DataTile {
fillValue: fillValue,
pool: pool,
interleave: false,
});
};
if (readRGB(this.convertToRGB_, image)) {
requests[sourceIndex] = image.readRGB(readOptions);
} else {
requests[sourceIndex] = image.readRasters(readOptions);
}
// requests after `sourceCount` are for mask data (if any)
const maskIndex = sourceCount + sourceIndex;

View File

@@ -3,7 +3,7 @@ import TileState from '../../../../../src/ol/TileState.js';
describe('ol/source/GeoTIFF', function () {
describe('constructor', function () {
it('configures readMethod_ to read rasters', function () {
it('sets convertToRGB false by default', function () {
const source = new GeoTIFFSource({
sources: [
{
@@ -11,10 +11,10 @@ describe('ol/source/GeoTIFF', function () {
},
],
});
expect(source.readMethod_).to.be('readRasters');
expect(source.convertToRGB_).to.be(false);
});
it('configures readMethod_ to read RGB', function () {
it('respects the convertToRGB option', function () {
const source = new GeoTIFFSource({
convertToRGB: true,
sources: [
@@ -23,7 +23,19 @@ describe('ol/source/GeoTIFF', function () {
},
],
});
expect(source.readMethod_).to.be('readRGB');
expect(source.convertToRGB_).to.be(true);
});
it('accepts auto convertToRGB', function () {
const source = new GeoTIFFSource({
convertToRGB: 'auto',
sources: [
{
url: 'spec/ol/source/images/0-0-0.tif',
},
],
});
expect(source.convertToRGB_).to.be('auto');
});
it('defaults to wrapX: false', function () {

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -0,0 +1,22 @@
import GeoTIFF from '../../../../src/ol/source/GeoTIFF.js';
import Map from '../../../../src/ol/Map.js';
import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
const source = new GeoTIFF({
convertToRGB: 'auto',
sources: [{url: '/data/raster/masked.tif'}],
});
new Map({
layers: [
new TileLayer({
source: source,
}),
],
target: 'map',
view: source.getView(),
});
render({
message: 'automatically converts to rgb',
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,22 @@
import GeoTIFF from '../../../../src/ol/source/GeoTIFF.js';
import Map from '../../../../src/ol/Map.js';
import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
const source = new GeoTIFF({
convertToRGB: false,
sources: [{url: '/data/raster/masked.tif'}],
});
new Map({
layers: [
new TileLayer({
source: source,
}),
],
target: 'map',
view: source.getView(),
});
render({
message: 'can be overridden to read raw YCbCr',
});