batch_resize
Resize multiple Aseprite files at once by specifying target dimensions, scale factors, or maintaining aspect ratios for pixel art projects.
Instructions
Batch resize multiple Aseprite files.
Args: input_dir: Directory containing input files output_dir: Directory for resized files width: Target width (optional) height: Target height (optional) scale: Scale factor (optional, alternative to width/height) maintain_aspect_ratio: Maintain aspect ratio when resizing file_pattern: File pattern to match (default: "*.aseprite")
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| input_dir | Yes | ||
| output_dir | Yes | ||
| width | No | ||
| height | No | ||
| scale | No | ||
| maintain_aspect_ratio | No | ||
| file_pattern | No | *.aseprite |
Implementation Reference
- aseprite_mcp/tools/batch.py:121-242 (handler)The batch_resize tool handles resizing multiple Aseprite files by building a Lua script and executing it via a command handler.
@mcp.tool() async def batch_resize( input_dir: str, output_dir: str, width: Optional[int] = None, height: Optional[int] = None, scale: Optional[float] = None, maintain_aspect_ratio: bool = True, file_pattern: str = "*.aseprite" ) -> str: """Batch resize multiple Aseprite files. Args: input_dir: Directory containing input files output_dir: Directory for resized files width: Target width (optional) height: Target height (optional) scale: Scale factor (optional, alternative to width/height) maintain_aspect_ratio: Maintain aspect ratio when resizing file_pattern: File pattern to match (default: "*.aseprite") """ try: # Validate inputs input_path = validate_file_path(input_dir, must_exist=True) output_path = validate_file_path(output_dir, must_exist=True) if not input_path.is_dir(): raise ValidationError("input_dir", str(input_path), "Must be a directory") if not output_path.is_dir(): raise ValidationError("output_dir", str(output_path), "Must be a directory") # Must provide either scale or dimensions if scale is None and width is None and height is None: raise ValidationError("parameters", None, "Must provide either scale or width/height") # Find all matching files files = list(input_path.glob(file_pattern)) if not files: return f"No files matching '{file_pattern}' found in {input_path}" # Build resize script builder = LuaBuilder() # Batch process each file results = [] errors = [] for file in files: try: builder = LuaBuilder() builder.open_sprite(str(file)) builder.add_line('local spr = app.activeSprite') builder.if_condition('not spr') builder.add_line('error("Failed to open sprite")') builder.end_if() # Calculate new dimensions if scale is not None: builder.add_line(f'local newWidth = math.floor(spr.width * {scale})') builder.add_line(f'local newHeight = math.floor(spr.height * {scale})') else: if width and height: if maintain_aspect_ratio: builder.add_line(f'local aspectRatio = spr.width / spr.height') builder.add_line(f'local targetRatio = {width} / {height}') builder.if_condition('aspectRatio > targetRatio') builder.add_line(f'local newWidth = {width}') builder.add_line(f'local newHeight = math.floor({width} / aspectRatio)') builder.else_block() builder.add_line(f'local newHeight = {height}') builder.add_line(f'local newWidth = math.floor({height} * aspectRatio)') builder.end_if() else: builder.add_line(f'local newWidth = {width}') builder.add_line(f'local newHeight = {height}') elif width: builder.add_line(f'local newWidth = {width}') builder.add_line(f'local newHeight = math.floor(spr.height * ({width} / spr.width))') else: # height only builder.add_line(f'local newHeight = {height}') builder.add_line(f'local newWidth = math.floor(spr.width * ({height} / spr.height))') # Resize sprite builder.add_line('app.command.SpriteSize{width=newWidth, height=newHeight}') # Save to output directory output_file = output_path / file.name builder.save_sprite(str(output_file)) # Execute cmd = get_command() success, output = cmd.execute_lua_script(builder.build()) results.append(f"Resized: {file.name}") except Exception as e: errors.append(f"Failed {file.name}: {e}") if not get_config().batch.continue_on_error: break # Summary summary = f"Batch resize completed:\n" summary += f"- Processed: {len(results)} files\n" summary += f"- Failed: {len(errors)} files\n" if results: summary += "\nSuccessful:\n" + "\n".join(results[:10]) if len(results) > 10: summary += f"\n... and {len(results) - 10} more" if errors: summary += "\n\nErrors:\n" + "\n".join(errors[:5]) if len(errors) > 5: summary += f"\n... and {len(errors) - 5} more" return summary except (ValidationError, AsepriteError) as e: return f"Failed to batch resize: {e}" except Exception as e: return f"Unexpected error: {e}"