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)
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)
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.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())