BugFixes
This commit is contained in:
@@ -75,7 +75,10 @@ def save_image_variants(
|
||||
source_max_dim = max(source_h, source_w)
|
||||
|
||||
# 1. Use provided configuration inputs (already available as function arguments)
|
||||
logger.info(f"Saving variants for map type: {base_map_type}")
|
||||
logger.info(f"SaveImageVariants: Starting for map type: {base_map_type}. Source shape: {source_image_data.shape}, Source bit depths: {source_bit_depth_info}")
|
||||
logger.debug(f"SaveImageVariants: Resolutions: {image_resolutions}, File Type Defs: {file_type_defs.keys()}, Output Formats: 8bit={output_format_8bit}, 16bit_pri={output_format_16bit_primary}, 16bit_fall={output_format_16bit_fallback}")
|
||||
logger.debug(f"SaveImageVariants: PNG Comp: {png_compression_level}, JPG Qual: {jpg_quality}")
|
||||
logger.debug(f"SaveImageVariants: Output Tokens: {output_filename_pattern_tokens}, Output Pattern: {output_filename_pattern}")
|
||||
|
||||
# 2. Determine Target Bit Depth
|
||||
target_bit_depth = 8 # Default
|
||||
@@ -111,46 +114,54 @@ def save_image_variants(
|
||||
logger.error(f"Unsupported target bit depth: {target_bit_depth}. Defaulting to 8-bit format.")
|
||||
output_ext = output_format_8bit.lstrip('.').lower()
|
||||
|
||||
logger.info(f"Target bit depth: {target_bit_depth}, Output format: {output_ext}")
|
||||
logger.info(f"SaveImageVariants: Determined target bit depth: {target_bit_depth}, Output format: {output_ext} for map type {base_map_type}")
|
||||
|
||||
# 4. Generate and Save Resolution Variants
|
||||
# Sort resolutions by max dimension descending
|
||||
sorted_resolutions = sorted(image_resolutions.items(), key=lambda item: item[1], reverse=True)
|
||||
|
||||
for res_key, res_max_dim in sorted_resolutions:
|
||||
logger.info(f"Processing resolution variant: {res_key} ({res_max_dim} max dim)")
|
||||
logger.info(f"SaveImageVariants: Processing variant {res_key} ({res_max_dim}px) for {base_map_type}")
|
||||
|
||||
# Calculate target dimensions, ensuring no upscaling
|
||||
if source_max_dim <= res_max_dim:
|
||||
# If source is smaller or equal, use source dimensions
|
||||
# --- Prevent Upscaling ---
|
||||
# Skip this resolution variant if its target dimension is larger than the source image's largest dimension.
|
||||
if res_max_dim > source_max_dim:
|
||||
logger.info(f"SaveImageVariants: Skipping variant {res_key} ({res_max_dim}px) for {base_map_type} because target resolution is larger than source ({source_max_dim}px).")
|
||||
continue # Skip to the next resolution
|
||||
|
||||
# Calculate target dimensions for valid variants (equal or smaller than source)
|
||||
if source_max_dim == res_max_dim:
|
||||
# Use source dimensions if target is equal
|
||||
target_w_res, target_h_res = source_w, source_h
|
||||
if source_max_dim < res_max_dim:
|
||||
logger.info(f"Source image ({source_w}x{source_h}) is smaller than target resolution {res_key} ({res_max_dim}). Saving at source resolution.")
|
||||
else:
|
||||
logger.info(f"SaveImageVariants: Using source resolution ({source_w}x{source_h}) for {res_key} variant of {base_map_type} as target matches source.")
|
||||
else: # Downscale (source_max_dim > res_max_dim)
|
||||
# Downscale, maintaining aspect ratio
|
||||
aspect_ratio = source_w / source_h
|
||||
if source_w > source_h:
|
||||
if source_w >= source_h: # Use >= to handle square images correctly
|
||||
target_w_res = res_max_dim
|
||||
target_h_res = int(res_max_dim / aspect_ratio)
|
||||
target_h_res = max(1, int(res_max_dim / aspect_ratio)) # Ensure height is at least 1
|
||||
else:
|
||||
target_h_res = res_max_dim
|
||||
target_w_res = int(res_max_dim * aspect_ratio)
|
||||
logger.info(f"Resizing source image ({source_w}x{source_h}) to {target_w_res}x{target_h_res} for {res_key} variant.")
|
||||
target_w_res = max(1, int(res_max_dim * aspect_ratio)) # Ensure width is at least 1
|
||||
logger.info(f"SaveImageVariants: Calculated downscale for {base_map_type} {res_key}: from ({source_w}x{source_h}) to ({target_w_res}x{target_h_res})")
|
||||
|
||||
|
||||
# Resize source_image_data
|
||||
# Use INTER_AREA for downscaling, INTER_LINEAR or INTER_CUBIC for upscaling (though we avoid upscaling here)
|
||||
interpolation_method = cv2.INTER_AREA # Good for downscaling
|
||||
# If we were allowing upscaling, we might add logic like:
|
||||
# if target_w_res > source_w or target_h_res > source_h:
|
||||
# interpolation_method = cv2.INTER_LINEAR # Or INTER_CUBIC
|
||||
|
||||
try:
|
||||
variant_data = ipu.resize_image(source_image_data, (target_w_res, target_h_res), interpolation=interpolation_method)
|
||||
logger.debug(f"Resized variant data shape: {variant_data.shape}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error resizing image for {res_key} variant: {e}")
|
||||
continue # Skip this variant if resizing fails
|
||||
# Resize source_image_data (only if necessary)
|
||||
if (target_w_res, target_h_res) == (source_w, source_h):
|
||||
# No resize needed if dimensions match
|
||||
variant_data = source_image_data.copy() # Copy to avoid modifying original if needed later
|
||||
logger.debug(f"SaveImageVariants: No resize needed for {base_map_type} {res_key}, using copy of source data.")
|
||||
else:
|
||||
# Perform resize only if dimensions differ (i.e., downscaling)
|
||||
interpolation_method = cv2.INTER_AREA # Good for downscaling
|
||||
try:
|
||||
variant_data = ipu.resize_image(source_image_data, target_w_res, target_h_res, interpolation=interpolation_method)
|
||||
if variant_data is None: # Check if resize failed
|
||||
raise ValueError("ipu.resize_image returned None")
|
||||
logger.debug(f"SaveImageVariants: Resized variant data shape for {base_map_type} {res_key}: {variant_data.shape}")
|
||||
except Exception as e:
|
||||
logger.error(f"SaveImageVariants: Error resizing image for {base_map_type} {res_key} variant: {e}")
|
||||
continue # Skip this variant if resizing fails
|
||||
|
||||
# Filename Construction
|
||||
current_tokens = output_filename_pattern_tokens.copy()
|
||||
@@ -172,14 +183,14 @@ def save_image_variants(
|
||||
continue # Skip this variant
|
||||
|
||||
output_path = output_base_directory / filename
|
||||
logger.info(f"Constructed output path: {output_path}")
|
||||
logger.info(f"SaveImageVariants: Constructed output path for {base_map_type} {res_key}: {output_path}")
|
||||
|
||||
# Ensure parent directory exists
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
logger.debug(f"Ensured directory exists: {output_path.parent}")
|
||||
logger.debug(f"SaveImageVariants: Ensured directory exists for {base_map_type} {res_key}: {output_path.parent}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error constructing filepath for {res_key} variant: {e}")
|
||||
logger.error(f"SaveImageVariants: Error constructing filepath for {base_map_type} {res_key} variant: {e}")
|
||||
continue # Skip this variant if path construction fails
|
||||
|
||||
|
||||
@@ -188,37 +199,40 @@ def save_image_variants(
|
||||
if output_ext == 'jpg':
|
||||
save_params_cv2.append(cv2.IMWRITE_JPEG_QUALITY)
|
||||
save_params_cv2.append(jpg_quality)
|
||||
logger.debug(f"Using JPG quality: {jpg_quality}")
|
||||
logger.debug(f"SaveImageVariants: Using JPG quality: {jpg_quality} for {base_map_type} {res_key}")
|
||||
elif output_ext == 'png':
|
||||
save_params_cv2.append(cv2.IMWRITE_PNG_COMPRESSION)
|
||||
save_params_cv2.append(png_compression_level)
|
||||
logger.debug(f"Using PNG compression level: {png_compression_level}")
|
||||
logger.debug(f"SaveImageVariants: Using PNG compression level: {png_compression_level} for {base_map_type} {res_key}")
|
||||
# Add other format specific parameters if needed (e.g., TIFF compression)
|
||||
|
||||
|
||||
# Bit Depth Conversion (just before saving)
|
||||
image_data_for_save = variant_data
|
||||
try:
|
||||
if target_bit_depth == 8:
|
||||
image_data_for_save = ipu.convert_to_uint8(variant_data)
|
||||
logger.debug("Converted variant data to uint8.")
|
||||
elif target_bit_depth == 16:
|
||||
# ipu.convert_to_uint16 might handle different input types (float, uint8)
|
||||
# Assuming variant_data might be float after resizing, convert to uint16
|
||||
image_data_for_save = ipu.convert_to_uint16(variant_data)
|
||||
logger.debug("Converted variant data to uint16.")
|
||||
# Add other bit depth conversions if needed
|
||||
except Exception as e:
|
||||
logger.error(f"Error converting image data to target bit depth {target_bit_depth} for {res_key} variant: {e}")
|
||||
continue # Skip this variant if conversion fails
|
||||
# Bit Depth Conversion is handled by ipu.save_image via output_dtype_target
|
||||
image_data_for_save = variant_data # Use the resized variant data directly
|
||||
|
||||
# Determine the target dtype for ipu.save_image
|
||||
output_dtype_for_save: Optional[np.dtype] = None
|
||||
if target_bit_depth == 8:
|
||||
output_dtype_for_save = np.uint8
|
||||
elif target_bit_depth == 16:
|
||||
output_dtype_for_save = np.uint16
|
||||
# Add other target bit depths like float16/float32 if necessary
|
||||
# elif target_bit_depth == 32: # Assuming float32 for EXR etc.
|
||||
# output_dtype_for_save = np.float32
|
||||
|
||||
|
||||
# Saving
|
||||
try:
|
||||
# ipu.save_image is expected to handle the actual cv2.imwrite call
|
||||
success = ipu.save_image(str(output_path), image_data_for_save, params=save_params_cv2)
|
||||
logger.debug(f"SaveImageVariants: Attempting to save {base_map_type} {res_key} to {output_path} with params {save_params_cv2}, target_dtype: {output_dtype_for_save}")
|
||||
success = ipu.save_image(
|
||||
str(output_path),
|
||||
image_data_for_save,
|
||||
output_dtype_target=output_dtype_for_save, # Pass the target dtype
|
||||
params=save_params_cv2
|
||||
)
|
||||
if success:
|
||||
logger.info(f"Successfully saved {res_key} variant to {output_path}")
|
||||
logger.info(f"SaveImageVariants: Successfully saved {base_map_type} {res_key} variant to {output_path}")
|
||||
# Collect details for the returned list
|
||||
saved_file_details.append({
|
||||
'path': str(output_path),
|
||||
@@ -228,10 +242,10 @@ def save_image_variants(
|
||||
'dimensions': (target_w_res, target_h_res)
|
||||
})
|
||||
else:
|
||||
logger.error(f"Failed to save {res_key} variant to {output_path}")
|
||||
logger.error(f"SaveImageVariants: Failed to save {base_map_type} {res_key} variant to {output_path} (ipu.save_image returned False)")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving image for {res_key} variant to {output_path}: {e}")
|
||||
logger.error(f"SaveImageVariants: Error during ipu.save_image for {base_map_type} {res_key} variant to {output_path}: {e}", exc_info=True)
|
||||
# Continue to next variant even if one fails
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user