Skip to main content

I have a scenario where I need to convert the bit depth of a raster from 16 bit to 8 bit, or vice versa, but the type should remain the same. ie Gray16->Gray8, Int16 -> Int8, Red8 -> Red16, etc.

Given that the RasterBandInterpretationCoercer does not accept attribute values for the Destination Interpretation Type parameter, is there an alternate method to testFilter for all allowed types, and 14 hardcoded RasterBandInterpretationCoercers?

Hi @jdh,

The RasterBandInterpretationCoercer uses the function @ReinterpretRaster. If we run this function in the FMEFunctionCaller transformer, we gain the ability to set the output raster type from a feature attribute.

We can use the RasterBandPropertyExtractor to determine the band type, then map that to its output type in a new attribute for the function.

I am attaching a workspace to illustrate the process.

changerastertype.fmw


Hi @jdh, I think you can implement that with Python. Example:

import fmeobjects
class FeatureProcessor(object):
    def __init__(self):
        interpretationPairs = {
            (fmeobjects.FME_INTERPRETATION_UINT8, fmeobjects.FME_INTERPRETATION_UINT16),
            (fmeobjects.FME_INTERPRETATION_INT8, fmeobjects.FME_INTERPRETATION_INT16),
            (fmeobjects.FME_INTERPRETATION_GRAY8, fmeobjects.FME_INTERPRETATION_GRAY16),
            (fmeobjects.FME_INTERPRETATION_RED8, fmeobjects.FME_INTERPRETATION_RED16),
            (fmeobjects.FME_INTERPRETATION_GREEN8, fmeobjects.FME_INTERPRETATION_GREEN16),
            (fmeobjects.FME_INTERPRETATION_BLUE8, fmeobjects.FME_INTERPRETATION_BLUE16),
            (fmeobjects.FME_INTERPRETATION_ALPHA8, fmeobjects.FME_INTERPRETATION_ALPHA16),
        }
        self.interpretations = {k : v for k, v in interpretationPairs}
        self.interpretations.update({v : k for k, v in interpretationPairs})
        self.rasterTools = fmeobjects.FMERasterTools()
        
    def input(self, feature):
        # Retrieve raster object from the input feature.
        raster = feature.getGeometry()
        if not isinstance(raster, fmeobjects.FMERaster):
            feature.setAttribute('fme_rejection_code', 'UNSUPPORTED_GEOMETRY_TYPE')
            self.pyoutput(feature)
        
        # Collect band objects and remove them from the raster.
        bands = []
        for i in range(raster.getNumBands()):
            bands.append(raster.getBand(0))
            raster.removeBand(0)
            
        # Update interpretation for each band and append them to the raster.
        for b in bands:
            before = b.getProperties().getInterpretation()
            after = self.interpretations.get(before, None)
            if after != None:
                b = self.rasterTools.convertBandInterpretation(after, b)
            raster.appendBand(b)

        # Reset raster to the feature.
        feature.setGeometry(raster)
        self.pyoutput(feature)
        
    def close(self):
        pass