|
|
import io |
|
|
import logging |
|
|
from datetime import datetime |
|
|
from PIL import Image, ImageDraw, ImageOps |
|
|
import numpy as np |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
def apply_halftone(image, dot_size=10): |
|
|
"""Görüntüye halftone efekti uygular""" |
|
|
start_time = datetime.now() |
|
|
logger.info(f"Applying halftone effect - {start_time}") |
|
|
|
|
|
try: |
|
|
|
|
|
if isinstance(image, bytes): |
|
|
image = Image.open(io.BytesIO(image)) |
|
|
|
|
|
|
|
|
if image.mode != 'L': |
|
|
image = image.convert('L') |
|
|
|
|
|
|
|
|
orig_width, orig_height = image.size |
|
|
|
|
|
|
|
|
resize_factor = dot_size / 5 |
|
|
|
|
|
|
|
|
small_width = int(orig_width / resize_factor) |
|
|
small_height = int(orig_height / resize_factor) |
|
|
small_image = image.resize((small_width, small_height), Image.BILINEAR) |
|
|
|
|
|
|
|
|
output_image = Image.new('L', (orig_width, orig_height), 255) |
|
|
draw = ImageDraw.Draw(output_image) |
|
|
|
|
|
|
|
|
for y in range(small_height): |
|
|
for x in range(small_width): |
|
|
|
|
|
brightness = 255 - small_image.getpixel((x, y)) |
|
|
|
|
|
|
|
|
radius = int((brightness / 255) * (dot_size / 2)) |
|
|
|
|
|
|
|
|
if radius > 0: |
|
|
center_x = int((x * resize_factor) + (resize_factor / 2)) |
|
|
center_y = int((y * resize_factor) + (resize_factor / 2)) |
|
|
bbox = [ |
|
|
center_x - radius, |
|
|
center_y - radius, |
|
|
center_x + radius, |
|
|
center_y + radius |
|
|
] |
|
|
draw.ellipse(bbox, fill=0) |
|
|
|
|
|
duration = (datetime.now() - start_time).total_seconds() |
|
|
logger.info(f"Successfully processed. Duration: {duration} seconds") |
|
|
return output_image |
|
|
|
|
|
except Exception as e: |
|
|
logger.error(f"Halftone processing error: {str(e)}", exc_info=True) |
|
|
raise |