112 lines
3.9 KiB
Python
112 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
from PIL import Image, ImageDraw, ImageFilter
|
|
import os
|
|
|
|
def add_border_and_resize(input_path, output_path, target_size=(1080, 1920), border_color=(255, 255, 255), border_width=20):
|
|
img = Image.open(input_path)
|
|
original_width, original_height = img.size
|
|
aspect_ratio = original_width / original_height
|
|
target_aspect = target_size[0] / target_size[1]
|
|
|
|
if aspect_ratio > target_aspect:
|
|
new_width = target_size[0] - border_width * 2
|
|
new_height = int(new_width / aspect_ratio)
|
|
else:
|
|
new_height = target_size[1] - border_width * 2
|
|
new_width = int(new_height * aspect_ratio)
|
|
|
|
img_resized = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
|
|
paste_x = (target_size[0] - new_width) // 2
|
|
paste_y = (target_size[1] - new_height) // 2
|
|
|
|
shadow_offset = 8
|
|
shadow_rect = [
|
|
paste_x + shadow_offset,
|
|
paste_y + shadow_offset,
|
|
paste_x + new_width + shadow_offset,
|
|
paste_y + new_height + shadow_offset
|
|
]
|
|
shadow_layer = Image.new('RGBA', target_size, (0, 0, 0, 0))
|
|
shadow_draw = ImageDraw.Draw(shadow_layer)
|
|
shadow_draw.rectangle(shadow_rect, fill=(0, 0, 0, 60))
|
|
shadow_blurred = shadow_layer.filter(ImageFilter.GaussianBlur(radius=10))
|
|
|
|
final_image = Image.new('RGB', target_size, border_color)
|
|
|
|
if shadow_blurred.mode == 'RGBA':
|
|
final_image.paste(shadow_blurred, (0, 0), shadow_blurred)
|
|
else:
|
|
final_rgb_shadow = shadow_blurred.convert('RGB')
|
|
final_image.paste(final_rgb_shadow, (0, 0))
|
|
|
|
final_image.paste(img_resized, (paste_x, paste_y))
|
|
|
|
draw = ImageDraw.Draw(final_image)
|
|
rect = [paste_x - 2, paste_y - 2, paste_x + new_width + 2, paste_y + new_height + 2]
|
|
for i in range(3):
|
|
offset = i + 1
|
|
current_rect = [
|
|
rect[0] - offset,
|
|
rect[1] - offset,
|
|
rect[2] + offset,
|
|
rect[3] + offset
|
|
]
|
|
draw.rectangle(current_rect, outline=(180, 200, 220))
|
|
|
|
for i in range(border_width):
|
|
current_rect = [
|
|
rect[0] - i - 3,
|
|
rect[1] - i - 3,
|
|
rect[2] + i + 3,
|
|
rect[3] + i + 3
|
|
]
|
|
color_with_alpha = (200 + i*2, 210 + i*2, 230 + i*2)
|
|
draw.rectangle(current_rect, outline=color_with_alpha)
|
|
|
|
final_image.save(output_path, quality=95)
|
|
print(f'[OK] Processed: {os.path.basename(input_path)} -> {output_path}')
|
|
return True
|
|
|
|
def main():
|
|
input_files = [
|
|
r'e:\project\flutter\f\mom_kitchen\docs\design\1.jpg',
|
|
r'e:\project\flutter\f\mom_kitchen\docs\design\2.jpg',
|
|
r'e:\project\flutter\f\mom_kitchen\docs\design\3.jpg',
|
|
r'e:\project\flutter\f\mom_kitchen\docs\design\4.jpg',
|
|
r'e:\project\flutter\f\mom_kitchen\docs\design\5.jpg',
|
|
]
|
|
|
|
output_dir = r'e:\project\flutter\f\mom_kitchen\docs\design\processed\portrait'
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
print('='*50)
|
|
print('Image Border Processing Script (Portrait Mode)')
|
|
print(f'Target Size: 1080 x 1920 px (Vertical)')
|
|
print(f'Processing: {len(input_files)} images')
|
|
print('='*50)
|
|
print()
|
|
|
|
success_count = 0
|
|
for input_file in input_files:
|
|
if os.path.exists(input_file):
|
|
filename = os.path.basename(input_file)
|
|
output_path = os.path.join(output_dir, f'bordered_portrait_{filename}')
|
|
try:
|
|
add_border_and_resize(input_file, output_path)
|
|
success_count += 1
|
|
except Exception as e:
|
|
print(f'[ERROR] Failed to process: {filename} - {str(e)}')
|
|
import traceback
|
|
traceback.print_exc()
|
|
else:
|
|
print(f'[WARNING] File not found: {input_file}')
|
|
|
|
print()
|
|
print('='*50)
|
|
print(f'[DONE] Processed {success_count}/{len(input_files)} images successfully!')
|
|
print(f'Output directory: {output_dir}')
|
|
print('='*50)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|