[PYTHON] Blurring image files with python

PYTHON
import sys
import os
from PyQt6.QtWidgets import (QApplication, QMainWindow, QLabel, QPushButton,
QFileDialog, QVBoxLayout, QWidget)
from PyQt6.QtGui import QPixmap, QImage
from PyQt6.QtCore import Qt, QPoint
from PIL import Image, ImageFilter

class BlurWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Image Blur Tool")
self.setGeometry(100, 100, 800, 600) # 초기 창 크기

# UI 설정
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout(self.central_widget)

# 이미지 표시용 레이블
self.image_label = QLabel(self)
self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.layout.addWidget(self.image_label)

# 버튼들
self.load_button = QPushButton("이미지 불러오기", self)
self.load_button.clicked.connect(self.load_image)
self.layout.addWidget(self.load_button)

self.blur_mode_button = QPushButton("이미지 블러 지정", self)
self.blur_mode_button.clicked.connect(self.toggle_blur_mode)
self.blur_mode_button.setEnabled(False)
self.layout.addWidget(self.blur_mode_button)

self.save_button = QPushButton("이미지 저장", self)
self.save_button.clicked.connect(self.save_image)
self.save_button.setEnabled(False)
self.layout.addWidget(self.save_button)

# 변수 초기화
self.image = None
self.original_image = None
self.start_pos = None
self.end_pos = None
self.blur_strength = 10
self.original_file_name = None
self.blur_mode = False

def load_image(self):
file_name, _ = QFileDialog.getOpenFileName(
self, "이미지 열기", "", "Image Files (*.png *.jpg *.jpeg *.bmp)")
if file_name:
self.image = Image.open(file_name)
self.original_image = self.image.copy()
self.original_file_name = os.path.splitext(os.path.basename(file_name))[0]
self.display_image(self.image)
self.blur_mode_button.setEnabled(True)
self.save_button.setEnabled(True)

def display_image(self, pil_image):
qimage = pil_image.toqimage()
pixmap = QPixmap.fromImage(qimage)

# 이미지 크기를 3배로 스케일링
scaled_width = pixmap.width() * 1
scaled_height = pixmap.height() * 1
scaled_pixmap = pixmap.scaled(
scaled_width, scaled_height,
Qt.AspectRatioMode.KeepAspectRatio,
Qt.TransformationMode.SmoothTransformation
)

self.image_label.setPixmap(scaled_pixmap)

# 창 크기를 이미지 크기에 맞게 조정 (최소 800x600 보장)
new_width = max(800, scaled_pixmap.width() + 20) # 여백 추가
new_height = max(600, scaled_pixmap.height() + 100) # 버튼 공간 고려
self.resize(new_width, new_height)

def toggle_blur_mode(self):
self.blur_mode = not self.blur_mode
if self.blur_mode:
self.blur_mode_button.setText("블러 지정 완료")
else:
self.blur_mode_button.setText("이미지 블러 지정")
self.start_pos = None
self.end_pos = None

def mousePressEvent(self, event):
if self.blur_mode and self.image and event.button() == Qt.MouseButton.LeftButton:
self.start_pos = event.position().toPoint()

def mouseMoveEvent(self, event):
if self.blur_mode and self.image and event.buttons() & Qt.MouseButton.LeftButton:
self.end_pos = event.position().toPoint()
self.apply_blur()

def mouseReleaseEvent(self, event):
if self.blur_mode and self.image and event.button() == Qt.MouseButton.LeftButton:
self.end_pos = event.position().toPoint()
self.apply_blur()

def apply_blur(self):
if not self.start_pos or not self.end_pos or not self.image:
return

# 이미지 크기에 맞게 좌표 조정
label_size = self.image_label.size()
pixmap_size = self.image_label.pixmap().size()
scale_x = self.image.width / pixmap_size.width()
scale_y = self.image.height / pixmap_size.height()

# 시작점과 끝점 계산
x1 = int(self.start_pos.x() * scale_x)
y1 = int(self.start_pos.y() * scale_y)
x2 = int(self.end_pos.x() * scale_x)
y2 = int(self.end_pos.y() * scale_y)

# 좌표 정렬
left = max(0, min(x1, x2))
right = min(self.image.width, max(x1, x2))
top = max(0, min(y1, y2))
bottom = min(self.image.height, max(y1, y2))

if left >= right or top >= bottom:
return

# 블러 적용
blurred_region = self.original_image.copy()
region = blurred_region.crop((left, top, right, bottom))
blurred = region.filter(ImageFilter.GaussianBlur(radius=self.blur_strength))
blurred_region.paste(blurred, (left, top))

self.image = blurred_region
self.display_image(self.image)

def save_image(self):
if not self.image or not self.original_file_name:
return

folder = QFileDialog.getExistingDirectory(self, "저장 폴더 선택")
if folder:
save_name = f"{self.original_file_name}_blurred.png"
save_path = os.path.join(folder, save_name)
self.image.save(save_path, "PNG")
print(f"이미지가 {save_path}에 저장되었습니다.")

if __name__ == '__main__':
app = QApplication(sys.argv)
window = BlurWindow()
window.show()
sys.exit(app.exec())

댓글 쓰기

다음 이전