zakodium-oss/pixelium

Extract meta information and resolution

Closed this issue · 0 comments

All possible meta information about the image should be displayed in information

image

I have currently this code

const original = API.cache('original');
if (! original) return;

const meta=[];
let resolutionDPI=0;
let imagePixelSize='';

if (original.meta && original.meta.tiff && original.meta.tiff.tags) {
    var metaTags=original.meta.tiff.tags;
    for (var key of Object.keys(metaTags)) {
        meta.push({key, value: metaTags[key]});
    }
    if (metaTags.XResolution===metaTags.YResolution && metaTags.XResolution) {
        // https://www.awaresystems.be/imaging/tiff/tifftags/resolutionunit.html
        switch (metaTags.ResolutionUnit) {
            case 2: // the resolution is in inch
                resolutionDPI=metaTags.XResolution;
                break;
            case 3: // the resolution is in cm
                resolutionDPI=metaTags.XResolution*2.54;
                break;
        }
    }
}
API.createData('meta', meta);

let metaMisc=[];
if (original.meta && original.meta.tiff && original.meta.tiff.fields && original.meta.tiff.fields.get(34682)) {
    let lines=original.meta.tiff.fields.get(34682).split('</Data><Data>');
    lines.forEach( a => {
        var fields=a.split(/<\/Label><Value>|<\/Value><Unit>/);
        fields[0]=fields[0].replace(/^.*>/,'');
        fields[2]=fields[2].replace(/<.*$/,'');
        metaMisc.push( {
            key: fields[0],
            value: fields[1],
            unit: fields[2]
        })
    });
}
if (original.meta && original.meta.tiff && original.meta.tiff.fields && original.meta.tiff.fields.get(34119)) {
    let lines=original.meta.tiff.fields.get(34119).join('').split(/\r?\n/);
    lines.forEach( line => {
        if (! line.includes('=')) return;
        let fields=line.split(/ *= */);
        if (fields[0]==='Image Pixel Size') {
            imagePixelSize=fields[1];
        }
        metaMisc.push( {
            key: fields[0].trim(),
            value: fields.slice(1).join('=').trim(),
        })
    })
}
API.createData('metaMisc', metaMisc);


if (original.channels===1) {
    API.createData('greyHistogramFull', original.getHistogram({maxSlots: 2**original.bitDepth}));
} else {
    API.createData('greyHistogramFull', []);
}



const imageInfo={
    bitDepth: original.bitDepth,
    width: original.width,
    height: original.height,
    surface: original.size,
    means: original.mean,
    median: original.median,
    nbChannels: original.channels,
    nbComponents: original.components,
    min: original.min,
    max: original.max,
}


// some specific code to determine the resolution
const pixelSize = API.getData('pixelSize');
if (! pixelSize || ! pixelSize.SI) {
    if (resolutionDPI) {
        const magnification=metaMisc.filter(a => a.key=='Magnification');
        if (magnification.length===1) {
            const newPixelSize=30000/magnification[0].value/1e9;
            pixelSize.SI=newPixelSize;
            pixelSize.unit='nm';
            pixelSize.triggerChange();
        }
    }

    if (imagePixelSize) {
        const unit = mathjs.unit(imagePixelSize);
        pixelSize.SI=unit.value;
        pixelSize.unit=unit.formatUnits();
        pixelSize.triggerChange();
    }
}

If we have value with units it should use the type described here: https://github.com/cheminfo/cheminfo-types/blob/main/src/core/Value.d.ts

The demo image 'spheres.tif' is expected to contain all the meta information.