Spaces:
Sleeping
Sleeping
| """ | |
| Core SVG vectorization functionality. | |
| """ | |
| import os | |
| import tempfile | |
| import shutil | |
| from PIL import Image | |
| import vtracer | |
| from loguru import logger | |
| from .params import DEFAULT_PARAMS, validate_params | |
| def convert_image_to_svg(input_path, output_path, params=None): | |
| """ | |
| Convert an image to SVG format. | |
| Args: | |
| input_path (str): Path to input image | |
| output_path (str): Path for output SVG | |
| params (dict, optional): Conversion parameters | |
| Returns: | |
| str: Path to generated SVG file, or None on failure | |
| """ | |
| # Validate input | |
| if not input_path or not os.path.exists(input_path): | |
| logger.error(f"Input file not found: {input_path}") | |
| return None | |
| # Set up parameters | |
| if params is None: | |
| params = DEFAULT_PARAMS.copy() | |
| else: | |
| # Validate parameters | |
| is_valid, error_msg = validate_params(params) | |
| if not is_valid: | |
| logger.error(f"Invalid parameters: {error_msg}") | |
| return None | |
| # Create temporary directory for processing | |
| temp_dir = tempfile.mkdtemp() | |
| temp_input = os.path.join(temp_dir, "temp_input.jpg") | |
| try: | |
| # Process input image | |
| logger.info(f"Processing input image: {input_path}") | |
| img = Image.open(input_path) | |
| # Save as temporary file | |
| img.save(temp_input, "JPEG") | |
| logger.info(f"Created temporary file: {temp_input}") | |
| # Get absolute paths | |
| abs_output_path = os.path.abspath(output_path) | |
| logger.info(f"Starting conversion... Input: {temp_input}, Output: {abs_output_path}") | |
| # Convert image to SVG using VTracer | |
| vtracer.convert_image_to_svg_py( | |
| temp_input, | |
| abs_output_path, | |
| # Color settings | |
| colormode=params['COLORMODE'], | |
| hierarchical=params['HIERARCHICAL'], | |
| # Tracing settings | |
| mode=params['MODE'], | |
| filter_speckle=params['FILTER_SPECKLE'], | |
| color_precision=params['COLOR_PRECISION'], | |
| layer_difference=params['LAYER_DIFFERENCE'], | |
| # Path settings | |
| corner_threshold=params['CORNER_THRESHOLD'], | |
| length_threshold=params['LENGTH_THRESHOLD'], | |
| max_iterations=params['MAX_ITERATIONS'], | |
| splice_threshold=params['SPLICE_THRESHOLD'], | |
| path_precision=params['PATH_PRECISION'] | |
| ) | |
| logger.info(f"Conversion complete: '{input_path}' → '{abs_output_path}'") | |
| return abs_output_path | |
| except Exception as e: | |
| logger.error(f"Error during conversion: {str(e)}") | |
| import traceback | |
| logger.error(traceback.format_exc()) | |
| return None | |
| finally: | |
| # Clean up temporary directory | |
| try: | |
| shutil.rmtree(temp_dir) | |
| logger.info("Cleaned up temporary files") | |
| except Exception as e: | |
| logger.warning(f"Error cleaning up temporary files: {str(e)}") | |
| def process_single_image(input_path, output_path=None, params=None): | |
| """ | |
| Process a single image with optional parameter overrides. | |
| Args: | |
| input_path (str): Path to input image | |
| output_path (str, optional): Path for output SVG | |
| params (dict, optional): Parameter overrides | |
| Returns: | |
| str: Path to generated SVG file | |
| """ | |
| # Generate output path if not provided | |
| if output_path is None: | |
| output_dir = os.path.dirname(input_path) | |
| filename = os.path.splitext(os.path.basename(input_path))[0] | |
| output_path = os.path.join(output_dir, f"{filename}.svg") | |
| # Merge with default parameters | |
| actual_params = DEFAULT_PARAMS.copy() | |
| if params: | |
| actual_params.update(params) | |
| return convert_image_to_svg(input_path, output_path, actual_params) | |