78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
# sumaexcel/image.py
|
|
from typing import Optional, Tuple, Union
|
|
from pathlib import Path
|
|
import os
|
|
from PIL import Image
|
|
from openpyxl.drawing.image import Image as XLImage
|
|
from openpyxl.worksheet.worksheet import Worksheet
|
|
|
|
class ImageManager:
|
|
"""Handle image operations in Excel"""
|
|
|
|
def __init__(self, worksheet: Worksheet):
|
|
self.worksheet = worksheet
|
|
self.temp_dir = Path("/tmp/sumaexcel_images")
|
|
self.temp_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
def add_image(
|
|
self,
|
|
image_path: Union[str, Path],
|
|
cell_coordinates: Tuple[int, int],
|
|
size: Optional[Tuple[int, int]] = None,
|
|
keep_aspect_ratio: bool = True,
|
|
anchor_type: str = 'absolute'
|
|
) -> None:
|
|
"""Add image to worksheet at specified position"""
|
|
# Convert path to Path object
|
|
image_path = Path(image_path)
|
|
|
|
# Open and process image
|
|
with Image.open(image_path) as img:
|
|
# Get original size
|
|
orig_width, orig_height = img.size
|
|
|
|
# Calculate new size if specified
|
|
if size:
|
|
target_width, target_height = size
|
|
if keep_aspect_ratio:
|
|
ratio = min(target_width/orig_width, target_height/orig_height)
|
|
target_width = int(orig_width * ratio)
|
|
target_height = int(orig_height * ratio)
|
|
|
|
# Resize image
|
|
img = img.resize((target_width, target_height), Image.LANCZOS)
|
|
|
|
# Save temporary resized image
|
|
temp_path = self.temp_dir / f"temp_{image_path.name}"
|
|
img.save(temp_path)
|
|
image_path = temp_path
|
|
|
|
# Create Excel image object
|
|
excel_image = XLImage(str(image_path))
|
|
|
|
# Add to worksheet
|
|
self.worksheet.add_image(excel_image, anchor=f'{cell_coordinates[0]}{cell_coordinates[1]}')
|
|
|
|
def add_image_absolute(
|
|
self,
|
|
image_path: Union[str, Path],
|
|
position: Tuple[int, int],
|
|
size: Optional[Tuple[int, int]] = None
|
|
) -> None:
|
|
"""Add image with absolute positioning"""
|
|
excel_image = XLImage(str(image_path))
|
|
if size:
|
|
excel_image.width, excel_image.height = size
|
|
excel_image.anchor = 'absolute'
|
|
excel_image.top, excel_image.left = position
|
|
self.worksheet.add_image(excel_image)
|
|
|
|
def cleanup(self) -> None:
|
|
"""Clean up temporary files"""
|
|
for file in self.temp_dir.glob("temp_*"):
|
|
file.unlink()
|
|
|
|
def __del__(self):
|
|
"""Cleanup on object destruction"""
|
|
self.cleanup()
|