diff --git a/geest/core/convert_to_8bit.py b/geest/core/convert_to_8bit.py new file mode 100644 index 0000000..5b786bb --- /dev/null +++ b/geest/core/convert_to_8bit.py @@ -0,0 +1,57 @@ +import os +import processing +from qgis.core import QgsMessageLog, Qgis, QgsRasterLayer, QgsProject + + +class RasterConverter: + """ + A class to handle the conversion of rasters to 8-bit TIFFs. + """ + + def __init__(self, feedback=None): + """ + Initialize the RasterConverter with optional feedback for progress reporting. + :param feedback: Optional QgsFeedback object for reporting progress. + """ + self.feedback = feedback + + def convert_to_8bit(self, input_raster: str, output_raster: str) -> bool: + """ + Convert the input raster to an 8-bit TIFF using gdal:translate. + :param input_raster: Path to the input raster file. + :param output_raster: Path to the output 8-bit TIFF file. + :return: True if conversion is successful, False otherwise. + """ + QgsMessageLog.logMessage( + f"Converting {input_raster} to 8-bit TIFF at {output_raster}.", + tag="RasterConverter", + level=Qgis.Info, + ) + + params = { + "INPUT": input_raster, + "TARGET_CRS": None, # Use input CRS + "NODATA": -9999, + "COPY_SUBDATASETS": False, + "OPTIONS": "", + "EXTRA": "", + "DATA_TYPE": 1, # 1 = Byte (8-bit unsigned) + "OUTPUT": output_raster, + } + + try: + # Run the gdal:translate processing algorithm + processing.run("gdal:translate", params, feedback=self.feedback) + QgsMessageLog.logMessage( + f"Successfully converted {input_raster} to 8-bit TIFF.", + tag="RasterConverter", + level=Qgis.Info, + ) + return True + except Exception as e: + QgsMessageLog.logMessage( + f"Failed to convert {input_raster} to 8-bit: {str(e)}", + tag="RasterConverter", + level=Qgis.Critical, + ) + return False diff --git a/test/test_convert_to_8bit.py b/test/test_convert_to_8bit.py new file mode 100644 index 0000000..ac2dac7 --- /dev/null +++ b/test/test_convert_to_8bit.py @@ -0,0 +1,53 @@ +import os +import unittest +from qgis.core import QgsApplication, QgsRasterLayer, Qgis +from geest.core.convert_to_8bit import RasterConverter + + +class TestRasterConverter(unittest.TestCase): + + @classmethod + def setUpClass(self): + + # Define paths to input and output files + self.input_raster = os.path.join( + os.path.dirname(__file__), "test_data/rasters/raster.tif" + ) + self.output_raster = os.path.join( + os.path.dirname(__file__), "output/output_raster_8bit.tif" + ) + + def test_convert_to_8bit(self): + """ + Test the convert_to_8bit method of the RasterConverter class. + """ + # Create an instance of RasterConverter + converter = RasterConverter() + + # Ensure input file exists before running the test + self.assertTrue( + os.path.exists(self.input_raster), "Input raster file does not exist" + ) + + # Run the conversion + success = converter.convert_to_8bit(self.input_raster, self.output_raster) + + # Check if the conversion was successful + self.assertTrue(success, "Raster conversion failed") + + # Check if the output image is 8-bit using QGIS API + raster_layer = QgsRasterLayer(self.output_raster, "Test Raster") + self.assertTrue(raster_layer.isValid(), "Raster layer is not valid") + + # Get the raster band data type + provider = raster_layer.dataProvider() + band_data_type = provider.dataType( + 1 + ) # Assuming we're working with the first band (1-indexed) + + # Assert if the raster data type is 8-bit + self.assertEqual(band_data_type, Qgis.Byte, "Output raster is not 8-bit") + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_data/rasters/raster.tif b/test/test_data/rasters/raster.tif new file mode 100644 index 0000000..1ee74bd Binary files /dev/null and b/test/test_data/rasters/raster.tif differ