mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-09 14:54:46 +03:00
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
This commit is contained in:
parent
7eb8393c5b
commit
50c1a19a54
|
@ -1,11 +1,12 @@
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
from PIL import Image
|
|
||||||
from cryptography.fernet import Fernet
|
from cryptography.fernet import Fernet
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
class ImageEncryption:
|
class ImageEncryption:
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, image_path, key_path=None):
|
def __init__(self, image_path, key_path=None):
|
||||||
"""
|
"""
|
||||||
클래스를 초기화합니다.
|
클래스를 초기화합니다.
|
||||||
|
@ -18,7 +19,7 @@ class ImageEncryption:
|
||||||
키 파일이 없으면 새로운 암호화 키를 생성하고, 이미지 파일을 엽니다.
|
키 파일이 없으면 새로운 암호화 키를 생성하고, 이미지 파일을 엽니다.
|
||||||
키 파일이 제공되면 파일에서 키를 읽어와 사용합니다.
|
키 파일이 제공되면 파일에서 키를 읽어와 사용합니다.
|
||||||
암호화에 사용될 Fernet 암호화 스위트도 초기화됩니다.
|
암호화에 사용될 Fernet 암호화 스위트도 초기화됩니다.
|
||||||
|
|
||||||
Initializes the class.
|
Initializes the class.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -32,10 +33,10 @@ class ImageEncryption:
|
||||||
"""
|
"""
|
||||||
self.image_path = image_path
|
self.image_path = image_path
|
||||||
if key_path is None:
|
if key_path is None:
|
||||||
self.key = Fernet.generate_key()
|
self.key = Fernet.generate_key()
|
||||||
self.image = Image.open(image_path)
|
self.image = Image.open(image_path)
|
||||||
else:
|
else:
|
||||||
with open(key_path, 'r') as key_file:
|
with open(key_path) as key_file:
|
||||||
self.key = key_file.read().encode()
|
self.key = key_file.read().encode()
|
||||||
print(self.key)
|
print(self.key)
|
||||||
self.cipher_suite = Fernet(self.key)
|
self.cipher_suite = Fernet(self.key)
|
||||||
|
@ -50,7 +51,7 @@ class ImageEncryption:
|
||||||
|
|
||||||
이미지 파일을 바이트로 읽어와서 Fernet을 사용하여 암호화한 후,
|
이미지 파일을 바이트로 읽어와서 Fernet을 사용하여 암호화한 후,
|
||||||
암호화된 데이터를 주어진 경로에 바이너리 형식으로 저장합니다.
|
암호화된 데이터를 주어진 경로에 바이너리 형식으로 저장합니다.
|
||||||
|
|
||||||
Encrypts the image.
|
Encrypts the image.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -59,21 +60,21 @@ class ImageEncryption:
|
||||||
Reads the image file as bytes and encrypts the data using Fernet.
|
Reads the image file as bytes and encrypts the data using Fernet.
|
||||||
Saves the encrypted data in binary format at the specified path.
|
Saves the encrypted data in binary format at the specified path.
|
||||||
"""
|
"""
|
||||||
with open(self.image_path, 'rb') as image_file:
|
with open(self.image_path, "rb") as image_file:
|
||||||
original_image_data = image_file.read()
|
original_image_data = image_file.read()
|
||||||
encrypted_data = self.cipher_suite.encrypt(original_image_data)
|
encrypted_data = self.cipher_suite.encrypt(original_image_data)
|
||||||
with open(savePath, 'wb') as encrypted_image_file:
|
with open(savePath, "wb") as encrypted_image_file:
|
||||||
encrypted_image_file.write(encrypted_data)
|
encrypted_image_file.write(encrypted_data)
|
||||||
|
|
||||||
# Get the directory of the image file
|
# Get the directory of the image file
|
||||||
directory = os.path.dirname(savePath)
|
directory = os.path.dirname(savePath)
|
||||||
# Create the path for the key file
|
# Create the path for the key file
|
||||||
key_path = os.path.join(directory, 'key.txt')
|
key_path = os.path.join(directory, "key.txt")
|
||||||
|
|
||||||
with open(key_path, 'w') as key_file:
|
with open(key_path, "w") as key_file:
|
||||||
key_file.write(self.key.decode())
|
key_file.write(self.key.decode())
|
||||||
|
|
||||||
#이미지를 복호화 (암호화 해제)하는 경우 savePath에 복호화된 이미지를 저장할 경로를 넣어주면 된다.
|
# 이미지를 복호화 (암호화 해제)하는 경우 savePath에 복호화된 이미지를 저장할 경로를 넣어주면 된다.
|
||||||
def decrypt_image(self, savePath):
|
def decrypt_image(self, savePath):
|
||||||
"""
|
"""
|
||||||
이미지를 복호화합니다.
|
이미지를 복호화합니다.
|
||||||
|
@ -83,7 +84,7 @@ class ImageEncryption:
|
||||||
|
|
||||||
암호화된 이미지 파일을 바이너리 모드로 읽어와서 Fernet을 사용하여 데이터를 복호화하고,
|
암호화된 이미지 파일을 바이너리 모드로 읽어와서 Fernet을 사용하여 데이터를 복호화하고,
|
||||||
복호화된 이미지를 지정된 경로에 저장합니다.
|
복호화된 이미지를 지정된 경로에 저장합니다.
|
||||||
|
|
||||||
Decrypts the image. Provide the path to save the decrypted image.
|
Decrypts the image. Provide the path to save the decrypted image.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -92,16 +93,15 @@ class ImageEncryption:
|
||||||
Reads the encrypted image file as bytes, decrypts the data using Fernet,
|
Reads the encrypted image file as bytes, decrypts the data using Fernet,
|
||||||
and saves the decrypted image at the specified path.
|
and saves the decrypted image at the specified path.
|
||||||
"""
|
"""
|
||||||
with open(self.image_path, 'rb') as encrypted_image_file:
|
with open(self.image_path, "rb") as encrypted_image_file:
|
||||||
encrypted_data = encrypted_image_file.read()
|
encrypted_data = encrypted_image_file.read()
|
||||||
decrypted_data = self.cipher_suite.decrypt(encrypted_data)
|
decrypted_data = self.cipher_suite.decrypt(encrypted_data)
|
||||||
decrypted_image = Image.open(io.BytesIO(decrypted_data))
|
decrypted_image = Image.open(io.BytesIO(decrypted_data))
|
||||||
if decrypted_image.mode == 'RGBA':
|
if decrypted_image.mode == "RGBA":
|
||||||
decrypted_image = decrypted_image.convert('RGB')
|
decrypted_image = decrypted_image.convert("RGB")
|
||||||
decrypted_image.save(savePath)
|
decrypted_image.save(savePath)
|
||||||
|
|
||||||
|
# to be deleted
|
||||||
#to be deleted
|
|
||||||
def decrypt_show_image(self, savePath):
|
def decrypt_show_image(self, savePath):
|
||||||
"""
|
"""
|
||||||
이미지를 복호화하고 복호화된 이미지 파일을 보여줍니다.
|
이미지를 복호화하고 복호화된 이미지 파일을 보여줍니다.
|
||||||
|
@ -111,7 +111,7 @@ class ImageEncryption:
|
||||||
|
|
||||||
암호화된 이미지 파일을 바이너리 모드로 읽어와서 Fernet을 사용하여 데이터를 복호화하고,
|
암호화된 이미지 파일을 바이너리 모드로 읽어와서 Fernet을 사용하여 데이터를 복호화하고,
|
||||||
복호화된 이미지를 지정된 경로에 저장합니다.
|
복호화된 이미지를 지정된 경로에 저장합니다.
|
||||||
|
|
||||||
Decrypts the image. And shows the decrypted image.
|
Decrypts the image. And shows the decrypted image.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -120,11 +120,11 @@ class ImageEncryption:
|
||||||
Reads the encrypted image file as bytes, decrypts the data using Fernet,
|
Reads the encrypted image file as bytes, decrypts the data using Fernet,
|
||||||
and saves the decrypted image at the specified path.
|
and saves the decrypted image at the specified path.
|
||||||
"""
|
"""
|
||||||
with open(self.image_path, 'rb') as encrypted_image_file:
|
with open(self.image_path, "rb") as encrypted_image_file:
|
||||||
encrypted_data = encrypted_image_file.read()
|
encrypted_data = encrypted_image_file.read()
|
||||||
decrypted_data = self.cipher_suite.decrypt(encrypted_data)
|
decrypted_data = self.cipher_suite.decrypt(encrypted_data)
|
||||||
decrypted_image = Image.open(io.BytesIO(decrypted_data))
|
decrypted_image = Image.open(io.BytesIO(decrypted_data))
|
||||||
if decrypted_image.mode == 'RGBA':
|
if decrypted_image.mode == "RGBA":
|
||||||
decrypted_image = decrypted_image.convert('RGB')
|
decrypted_image = decrypted_image.convert("RGB")
|
||||||
decrypted_image.save(savePath)
|
decrypted_image.save(savePath)
|
||||||
Image.open(savePath).show()
|
Image.open(savePath).show()
|
||||||
|
|
|
@ -1,63 +1,77 @@
|
||||||
import math
|
import math
|
||||||
import Image, ImageDraw,ImageFilter
|
|
||||||
|
import Image
|
||||||
|
import ImageDraw
|
||||||
|
import ImageFilter
|
||||||
|
|
||||||
|
|
||||||
class Gradation(ImageFilter):
|
class Gradation(ImageFilter):
|
||||||
|
name = "Gradation"
|
||||||
|
|
||||||
name ="Gradation"
|
def __init__(self, start_color, end_color, grad_dir="row"):
|
||||||
|
self.grad1 = start_color
|
||||||
|
self.grad2 = end_color
|
||||||
|
self.shape = grad_dir
|
||||||
|
|
||||||
def __init__(self,start_color,end_color,grad_dir='row'):
|
def apply_gradation_filter(self, image):
|
||||||
self.grad1=start_color
|
|
||||||
self.grad2=end_color
|
|
||||||
self.shape=grad_dir
|
|
||||||
|
|
||||||
def apply_gradation_filter(self,image):
|
|
||||||
# 그라데이션 필터 적용
|
# 그라데이션 필터 적용
|
||||||
width, height = image.size
|
width, height = image.size
|
||||||
|
|
||||||
if self.shape == 'row' or self.shape == 'col':
|
if self.shape == "row" or self.shape == "col":
|
||||||
grad_image = self.visual_gradation(width, height)
|
grad_image = self.visual_gradation(width, height)
|
||||||
elif self.shape == 'circular':
|
elif self.shape == "circular":
|
||||||
grad_image = self.circular_gradation(width, height, self.grad1, self.grad2)
|
grad_image = self.circular_gradation(width, height, self.grad1, self.grad2)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid shape. Use 'row', 'col', or 'circular'.")
|
raise ValueError("Invalid shape. Use 'row', 'col', or 'circular'.")
|
||||||
|
|
||||||
# 원본 이미지와 그라데이션 이미지를 합침
|
# 원본 이미지와 그라데이션 이미지를 합침
|
||||||
blended_image = Image.blend(image.convert('RGB'), grad_image, 0.5)
|
blended_image = Image.blend(image.convert("RGB"), grad_image, 0.5)
|
||||||
blended_image = blended_image.convert('RGB')
|
blended_image = blended_image.convert("RGB")
|
||||||
|
|
||||||
return blended_image
|
return blended_image
|
||||||
|
|
||||||
def visual_gradation(self,width, height):
|
def visual_gradation(self, width, height):
|
||||||
image = Image.new("RGB", (width, height))
|
image = Image.new("RGB", (width, height))
|
||||||
# 이미지 Draw 객체 생성
|
# 이미지 Draw 객체 생성
|
||||||
|
|
||||||
draw = ImageDraw.Draw(image)
|
draw = ImageDraw.Draw(image)
|
||||||
|
|
||||||
if self.shape == 'col':
|
if self.shape == "col":
|
||||||
for x in range(width):
|
for x in range(width):
|
||||||
# 색상 그라데이션 계산
|
# 색상 그라데이션 계산
|
||||||
red = int(self.grad1[0] * (1.0 - x / width) + self.grad2[0] * (x / width))
|
red = int(
|
||||||
green = int(self.grad1[1] * (1.0 - x / width) + self.grad2[1] * (x / width))
|
self.grad1[0] * (1.0 - x / width) + self.grad2[0] * (x / width)
|
||||||
blue = int(self.grad1[2] * (1.0 - x / width) + self.grad2[2] * (x / width))
|
)
|
||||||
|
green = int(
|
||||||
|
self.grad1[1] * (1.0 - x / width) + self.grad2[1] * (x / width)
|
||||||
|
)
|
||||||
|
blue = int(
|
||||||
|
self.grad1[2] * (1.0 - x / width) + self.grad2[2] * (x / width)
|
||||||
|
)
|
||||||
|
|
||||||
# 현재 열에 대한 선 그리기
|
# 현재 열에 대한 선 그리기
|
||||||
draw.line([(x, 0), (x, height)], fill=(red, green, blue))
|
draw.line([(x, 0), (x, height)], fill=(red, green, blue))
|
||||||
elif self.shape == 'row':
|
elif self.shape == "row":
|
||||||
for y in range(height):
|
for y in range(height):
|
||||||
# 색상 그라데이션 계산
|
# 색상 그라데이션 계산
|
||||||
red = int(self.grad1[0] * (1.0 - y / height) + self.grad2[0] * (y / height))
|
red = int(
|
||||||
green = int(self.grad1[1] * (1.0 - y / height) + self.grad2[1] * (y / height))
|
self.grad1[0] * (1.0 - y / height) + self.grad2[0] * (y / height)
|
||||||
blue = int(self.grad1[2] * (1.0 - y / height) + self.grad2[2] * (y / height))
|
)
|
||||||
|
green = int(
|
||||||
|
self.grad1[1] * (1.0 - y / height) + self.grad2[1] * (y / height)
|
||||||
|
)
|
||||||
|
blue = int(
|
||||||
|
self.grad1[2] * (1.0 - y / height) + self.grad2[2] * (y / height)
|
||||||
|
)
|
||||||
|
|
||||||
# 현재 열에 대한 선 그리기
|
# 현재 열에 대한 선 그리기
|
||||||
draw.line([(0, y), (width, y)], fill=(red, green, blue))
|
draw.line([(0, y), (width, y)], fill=(red, green, blue))
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid shape. Use 'row' or 'col'.")
|
raise ValueError("Invalid shape. Use 'row' or 'col'.")
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
def circular_gradation(self,width, height):
|
def circular_gradation(self, width, height):
|
||||||
|
|
||||||
# 새로운 이미지 생성
|
# 새로운 이미지 생성
|
||||||
image = Image.new("RGB", (width, height))
|
image = Image.new("RGB", (width, height))
|
||||||
|
|
||||||
|
@ -72,7 +86,7 @@ class Gradation(ImageFilter):
|
||||||
for y in range(height):
|
for y in range(height):
|
||||||
for x in range(width):
|
for x in range(width):
|
||||||
# 현재 좌표에서 중심 좌표까지의 거리 계산
|
# 현재 좌표에서 중심 좌표까지의 거리 계산
|
||||||
distance = math.sqrt((x - center_x)**2 + (y - center_y)**2)
|
distance = math.sqrt((x - center_x) ** 2 + (y - center_y) ** 2)
|
||||||
|
|
||||||
# 반지름보다 크면 거리를 반지름으로 설정
|
# 반지름보다 크면 거리를 반지름으로 설정
|
||||||
distance = min(distance, radius)
|
distance = min(distance, radius)
|
||||||
|
@ -86,4 +100,4 @@ class Gradation(ImageFilter):
|
||||||
# 현재 좌표에 색상 설정
|
# 현재 좌표에 색상 설정
|
||||||
draw.point((x, y), fill=(r, g, b))
|
draw.point((x, y), fill=(r, g, b))
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import os
|
|
||||||
|
|
||||||
def apply_mosaic_filter(image, block_size=20):
|
def apply_mosaic_filter(image, block_size=20):
|
||||||
"""
|
"""
|
||||||
주어진 이미지에 모자이크 기능을 적용
|
주어진 이미지에 모자이크 기능을 적용
|
||||||
|
|
||||||
매개변수 :
|
매개변수 :
|
||||||
- image(PIL.Image.Image) : 입력된 이미지값
|
- image(PIL.Image.Image) : 입력된 이미지값
|
||||||
- block_size (int): 모자이크 블록의 크기
|
- block_size (int): 모자이크 블록의 크기
|
||||||
|
|
||||||
반환 :
|
반환 :
|
||||||
- 모자이크 된 이미지
|
- 모자이크 된 이미지
|
||||||
"""
|
"""
|
||||||
|
|
||||||
width, height = image.size
|
width, height = image.size
|
||||||
|
|
||||||
# 입력 이미지와 동일한 모드와 동일한 크기의 새 이미지 생성
|
# 입력 이미지와 동일한 모드와 동일한 크기의 새 이미지 생성
|
||||||
|
@ -20,16 +20,15 @@ def apply_mosaic_filter(image, block_size=20):
|
||||||
|
|
||||||
for x in range(0, width, block_size):
|
for x in range(0, width, block_size):
|
||||||
for y in range(0, height, block_size):
|
for y in range(0, height, block_size):
|
||||||
|
|
||||||
# 원본 이미지에서 블록 잘라내기
|
# 원본 이미지에서 블록 잘라내기
|
||||||
box = (x, y, x + block_size, y + block_size)
|
box = (x, y, x + block_size, y + block_size)
|
||||||
block = image.crop(box)
|
block = image.crop(box)
|
||||||
|
|
||||||
# 블록의 평균 색상을 계산
|
# 블록의 평균 색상을 계산
|
||||||
average_color = (
|
average_color = (
|
||||||
sum(p[0] for p in block.getdata()) // block_size**2,
|
sum(p[0] for p in block.getdata()) // block_size**2,
|
||||||
sum(p[1] for p in block.getdata()) // block_size**2,
|
sum(p[1] for p in block.getdata()) // block_size**2,
|
||||||
sum(p[2] for p in block.getdata()) // block_size**2
|
sum(p[2] for p in block.getdata()) // block_size**2,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 평균 색상으로 새 이미지를 생성하여 필터링된 이미지에 붙여넣기
|
# 평균 색상으로 새 이미지를 생성하여 필터링된 이미지에 붙여넣기
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
from PIL import Image, ImageDraw
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
|
|
||||||
class GradationFilter:
|
class GradationFilter:
|
||||||
def __init__(self, image_path):
|
def __init__(self, image_path):
|
||||||
self.original_image = Image.open(image_path)
|
self.original_image = Image.open(image_path)
|
||||||
|
|
||||||
def apply_gradation_filter(self, start_color, end_color, input_alpha=0.5):
|
def apply_gradation_filter(self, start_color, end_color, input_alpha=0.5):
|
||||||
alpha_mask = self.original_image.convert("L").point(lambda x: 0 if x == 0 else 255)
|
alpha_mask = self.original_image.convert("L").point(
|
||||||
|
lambda x: 0 if x == 0 else 255
|
||||||
|
)
|
||||||
self.original_image.putalpha(alpha_mask)
|
self.original_image.putalpha(alpha_mask)
|
||||||
|
|
||||||
width, height = self.original_image.size
|
width, height = self.original_image.size
|
||||||
grad_image = self.visual_gradation(width, height, start_color, end_color)
|
grad_image = self.visual_gradation(width, height, start_color, end_color)
|
||||||
|
|
||||||
result_image = Image.alpha_composite(Image.new("RGBA", self.original_image.size, (0, 0, 0, 0)), grad_image)
|
result_image = Image.alpha_composite(
|
||||||
|
Image.new("RGBA", self.original_image.size, (0, 0, 0, 0)), grad_image
|
||||||
|
)
|
||||||
result_image.paste(self.original_image, (0, 0), self.original_image)
|
result_image.paste(self.original_image, (0, 0), self.original_image)
|
||||||
|
|
||||||
return result_image
|
return result_image
|
||||||
|
@ -30,11 +35,12 @@ class GradationFilter:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def hex_to_rgb(hex_color):
|
def hex_to_rgb(hex_color):
|
||||||
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
|
return tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
image_path = "Gradation/60D2151A-A12A-4F89-9D79-D7FD5DBEA4C4.png"
|
image_path = "Gradation/60D2151A-A12A-4F89-9D79-D7FD5DBEA4C4.png"
|
||||||
|
|
||||||
gradation_filter = GradationFilter(image_path)
|
gradation_filter = GradationFilter(image_path)
|
||||||
|
|
||||||
start_color_input = input("Enter start color (hex): ")
|
start_color_input = input("Enter start color (hex): ")
|
||||||
|
@ -46,7 +52,7 @@ try:
|
||||||
filtered_image = gradation_filter.apply_gradation_filter(start_color, end_color)
|
filtered_image = gradation_filter.apply_gradation_filter(start_color, end_color)
|
||||||
filtered_image.show()
|
filtered_image.show()
|
||||||
|
|
||||||
except IOError:
|
except OSError:
|
||||||
print("Error: Not a PNG file.")
|
print("Error: Not a PNG file.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"An unexpected error occurred: {e}")
|
print(f"An unexpected error occurred: {e}")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user