Source code for src.converters.png_from_ppm

"""
Author: Ismael Seidel (ismael.seidel@ufsc.br)
Affiliation: Embedded Computing Lab (ECL), Federal University of Santa Catarina (UFSC)

Description:
    This module contains the implementation of PPM 10 bits -> PNG 8 bits conversion using ffmpeg.
"""

import subprocess
from pathlib import Path
from typing import Union

from lfc_toolkit.src.data_handlers.encoding_orders import (
    ScanFunctionType,
    get_serpentine_scan_list,
)
from lfc_toolkit.src.data_handlers.formatters import get_view_name_with_leading_zeros
from lfc_toolkit.src.data_handlers.lightfield import (
    RAW_RGB_PNG_LightField_Data,
    RAW_RGB_PPM_LightField_Data,
)


[docs] def generate_png_from_ppm( raw_light_field_data: RAW_RGB_PPM_LightField_Data, png_path: Union[str, Path], scan_order: ScanFunctionType = get_serpentine_scan_list, remove_after_using: bool = False, ) -> RAW_RGB_PNG_LightField_Data: """ Get RAW PNG (RGB) light field object from RAW PPM (RGB) :param raw_light_field_data: RAW PPM light field to be converted :type raw_light_field_data: RAW_RGB_PPM_LightField_Data :param png_path: Path to save the PNG files :type png_path: Union[str, Path] :param scan_order: Function defining the scan order :type scan_order: ScanFunctionType :param remove_after_using: Whether to remove intermediate files :type remove_after_using: bool :return: Converted PNG light field data :rtype: RAW_RGB_PNG_LightField_Data """ assert raw_light_field_data.colour_space == "sRGB" assert raw_light_field_data.pix_fmt == "PPM" lightfield = raw_light_field_data.copy() output_raw_lf = RAW_RGB_PNG_LightField_Data( lightfield=lightfield, png_path=png_path, bpp_for_naming=raw_light_field_data.bpp_for_naming, remove_after_using=remove_after_using, ) scan_list = scan_order( raw_light_field_data.n_views_width, raw_light_field_data.n_views_height, 0, 0, 1, 1, ) # always in this format 0,0,1,1 as it is expected by the JPLM for x, y in scan_list: view_filename = f"{get_view_name_with_leading_zeros(x, y)}.ppm" input_ppm = raw_light_field_data.raw_path / view_filename output_png = ( output_raw_lf.raw_path / f"{get_view_name_with_leading_zeros(x, y)}.png" ) output_png.parent.mkdir(parents=True, exist_ok=True) cmd = [ "ffmpeg", "-y", "-i", str(input_ppm), "-pix_fmt", "rgb24", # 8 bits str(output_png), ] res = subprocess.run(cmd, capture_output=True) if res.returncode != 0: raise RuntimeError(f"Error in conversion PPM->PNG: {res.stderr.decode()}") return output_raw_lf
[docs] def main(): import argparse # 1. Create the ArgumentParser object with a description parser = argparse.ArgumentParser(description="Convert a single PPM LF to PNG.") # 2. Add a positional argument (required input, no dashes) parser.add_argument( "--name", "-n", required=True, type=str, help="The name of the light field." ) parser.add_argument("--n-views-height", "-t", required=True, type=int, help="T") parser.add_argument("--n-views-width", "-s", required=True, type=int, help="S") parser.add_argument("--view-height", "-v", required=True, type=int, help="V") parser.add_argument("--view-width", "-u", required=True, type=int, help="U") parser.add_argument( "--input_path", "-i", required=True, type=str, help="Input path" ) parser.add_argument( "--output_path", "-o", required=True, type=str, help="Output path" ) # 3. Parse the arguments from the command line args = parser.parse_args() from lfc_toolkit.src.data_handlers.lightfield import LightField lf = RAW_RGB_PPM_LightField_Data( lightfield=LightField( name=args.name, view_width=args.view_width, view_height=args.view_height, n_views_width=args.n_views_width, n_views_height=args.n_views_height, ), ppm_path=args.input_path, ) generate_png_from_ppm( raw_light_field_data=lf, png_path=args.output_path, remove_after_using=False )
if __name__ == "__main__": main()