mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-09 23:04:45 +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 os
|
||||
from PIL import Image
|
||||
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
class ImageEncryption:
|
||||
|
||||
|
||||
def __init__(self, image_path, key_path=None):
|
||||
"""
|
||||
클래스를 초기화합니다.
|
||||
|
@ -18,7 +19,7 @@ class ImageEncryption:
|
|||
키 파일이 없으면 새로운 암호화 키를 생성하고, 이미지 파일을 엽니다.
|
||||
키 파일이 제공되면 파일에서 키를 읽어와 사용합니다.
|
||||
암호화에 사용될 Fernet 암호화 스위트도 초기화됩니다.
|
||||
|
||||
|
||||
Initializes the class.
|
||||
|
||||
Parameters:
|
||||
|
@ -32,10 +33,10 @@ class ImageEncryption:
|
|||
"""
|
||||
self.image_path = image_path
|
||||
if key_path is None:
|
||||
self.key = Fernet.generate_key()
|
||||
self.image = Image.open(image_path)
|
||||
self.key = Fernet.generate_key()
|
||||
self.image = Image.open(image_path)
|
||||
else:
|
||||
with open(key_path, 'r') as key_file:
|
||||
with open(key_path) as key_file:
|
||||
self.key = key_file.read().encode()
|
||||
print(self.key)
|
||||
self.cipher_suite = Fernet(self.key)
|
||||
|
@ -50,7 +51,7 @@ class ImageEncryption:
|
|||
|
||||
이미지 파일을 바이트로 읽어와서 Fernet을 사용하여 암호화한 후,
|
||||
암호화된 데이터를 주어진 경로에 바이너리 형식으로 저장합니다.
|
||||
|
||||
|
||||
Encrypts the image.
|
||||
|
||||
Parameters:
|
||||
|
@ -59,21 +60,21 @@ class ImageEncryption:
|
|||
Reads the image file as bytes and encrypts the data using Fernet.
|
||||
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()
|
||||
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)
|
||||
|
||||
|
||||
# Get the directory of the image file
|
||||
directory = os.path.dirname(savePath)
|
||||
# Create the path for the key file
|
||||
key_path = os.path.join(directory, 'key.txt')
|
||||
|
||||
with open(key_path, 'w') as key_file:
|
||||
key_path = os.path.join(directory, "key.txt")
|
||||
|
||||
with open(key_path, "w") as key_file:
|
||||
key_file.write(self.key.decode())
|
||||
|
||||
#이미지를 복호화 (암호화 해제)하는 경우 savePath에 복호화된 이미지를 저장할 경로를 넣어주면 된다.
|
||||
# 이미지를 복호화 (암호화 해제)하는 경우 savePath에 복호화된 이미지를 저장할 경로를 넣어주면 된다.
|
||||
def decrypt_image(self, savePath):
|
||||
"""
|
||||
이미지를 복호화합니다.
|
||||
|
@ -83,7 +84,7 @@ class ImageEncryption:
|
|||
|
||||
암호화된 이미지 파일을 바이너리 모드로 읽어와서 Fernet을 사용하여 데이터를 복호화하고,
|
||||
복호화된 이미지를 지정된 경로에 저장합니다.
|
||||
|
||||
|
||||
Decrypts the image. Provide the path to save the decrypted image.
|
||||
|
||||
Parameters:
|
||||
|
@ -92,16 +93,15 @@ class ImageEncryption:
|
|||
Reads the encrypted image file as bytes, decrypts the data using Fernet,
|
||||
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()
|
||||
decrypted_data = self.cipher_suite.decrypt(encrypted_data)
|
||||
decrypted_image = Image.open(io.BytesIO(decrypted_data))
|
||||
if decrypted_image.mode == 'RGBA':
|
||||
decrypted_image = decrypted_image.convert('RGB')
|
||||
if decrypted_image.mode == "RGBA":
|
||||
decrypted_image = decrypted_image.convert("RGB")
|
||||
decrypted_image.save(savePath)
|
||||
|
||||
|
||||
#to be deleted
|
||||
|
||||
# to be deleted
|
||||
def decrypt_show_image(self, savePath):
|
||||
"""
|
||||
이미지를 복호화하고 복호화된 이미지 파일을 보여줍니다.
|
||||
|
@ -111,7 +111,7 @@ class ImageEncryption:
|
|||
|
||||
암호화된 이미지 파일을 바이너리 모드로 읽어와서 Fernet을 사용하여 데이터를 복호화하고,
|
||||
복호화된 이미지를 지정된 경로에 저장합니다.
|
||||
|
||||
|
||||
Decrypts the image. And shows the decrypted image.
|
||||
|
||||
Parameters:
|
||||
|
@ -120,11 +120,11 @@ class ImageEncryption:
|
|||
Reads the encrypted image file as bytes, decrypts the data using Fernet,
|
||||
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()
|
||||
decrypted_data = self.cipher_suite.decrypt(encrypted_data)
|
||||
decrypted_image = Image.open(io.BytesIO(decrypted_data))
|
||||
if decrypted_image.mode == 'RGBA':
|
||||
decrypted_image = decrypted_image.convert('RGB')
|
||||
if decrypted_image.mode == "RGBA":
|
||||
decrypted_image = decrypted_image.convert("RGB")
|
||||
decrypted_image.save(savePath)
|
||||
Image.open(savePath).show()
|
||||
Image.open(savePath).show()
|
||||
|
|
|
@ -1,63 +1,77 @@
|
|||
import math
|
||||
import Image, ImageDraw,ImageFilter
|
||||
import math
|
||||
|
||||
import Image
|
||||
import ImageDraw
|
||||
import 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'):
|
||||
self.grad1=start_color
|
||||
self.grad2=end_color
|
||||
self.shape=grad_dir
|
||||
|
||||
def apply_gradation_filter(self,image):
|
||||
def apply_gradation_filter(self, image):
|
||||
# 그라데이션 필터 적용
|
||||
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)
|
||||
elif self.shape == 'circular':
|
||||
elif self.shape == "circular":
|
||||
grad_image = self.circular_gradation(width, height, self.grad1, self.grad2)
|
||||
else:
|
||||
raise ValueError("Invalid shape. Use 'row', 'col', or 'circular'.")
|
||||
|
||||
# 원본 이미지와 그라데이션 이미지를 합침
|
||||
blended_image = Image.blend(image.convert('RGB'), grad_image, 0.5)
|
||||
blended_image = blended_image.convert('RGB')
|
||||
blended_image = Image.blend(image.convert("RGB"), grad_image, 0.5)
|
||||
blended_image = blended_image.convert("RGB")
|
||||
|
||||
return blended_image
|
||||
|
||||
def visual_gradation(self,width, height):
|
||||
def visual_gradation(self, width, height):
|
||||
image = Image.new("RGB", (width, height))
|
||||
# 이미지 Draw 객체 생성
|
||||
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
if self.shape == 'col':
|
||||
if self.shape == "col":
|
||||
for x in range(width):
|
||||
# 색상 그라데이션 계산
|
||||
red = int(self.grad1[0] * (1.0 - x / width) + self.grad2[0] * (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))
|
||||
red = int(
|
||||
self.grad1[0] * (1.0 - x / width) + self.grad2[0] * (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))
|
||||
elif self.shape == 'row':
|
||||
elif self.shape == "row":
|
||||
for y in range(height):
|
||||
# 색상 그라데이션 계산
|
||||
red = int(self.grad1[0] * (1.0 - y / height) + self.grad2[0] * (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))
|
||||
red = int(
|
||||
self.grad1[0] * (1.0 - y / height) + self.grad2[0] * (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))
|
||||
else:
|
||||
raise ValueError("Invalid shape. Use 'row' or 'col'.")
|
||||
|
||||
|
||||
return image
|
||||
|
||||
def circular_gradation(self,width, height):
|
||||
|
||||
def circular_gradation(self, width, height):
|
||||
# 새로운 이미지 생성
|
||||
image = Image.new("RGB", (width, height))
|
||||
|
||||
|
@ -72,7 +86,7 @@ class Gradation(ImageFilter):
|
|||
for y in range(height):
|
||||
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)
|
||||
|
@ -86,4 +100,4 @@ class Gradation(ImageFilter):
|
|||
# 현재 좌표에 색상 설정
|
||||
draw.point((x, y), fill=(r, g, b))
|
||||
|
||||
return image
|
||||
return image
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
from PIL import Image
|
||||
import os
|
||||
|
||||
|
||||
def apply_mosaic_filter(image, block_size=20):
|
||||
"""
|
||||
주어진 이미지에 모자이크 기능을 적용
|
||||
|
||||
매개변수 :
|
||||
|
||||
매개변수 :
|
||||
- image(PIL.Image.Image) : 입력된 이미지값
|
||||
- block_size (int): 모자이크 블록의 크기
|
||||
|
||||
|
||||
반환 :
|
||||
- 모자이크 된 이미지
|
||||
"""
|
||||
|
||||
|
||||
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 y in range(0, height, block_size):
|
||||
|
||||
# 원본 이미지에서 블록 잘라내기
|
||||
box = (x, y, x + block_size, y + block_size)
|
||||
block = image.crop(box)
|
||||
|
||||
|
||||
# 블록의 평균 색상을 계산
|
||||
average_color = (
|
||||
sum(p[0] 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
|
||||
|
||||
|
||||
class GradationFilter:
|
||||
def __init__(self, image_path):
|
||||
self.original_image = Image.open(image_path)
|
||||
|
||||
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)
|
||||
|
||||
width, height = self.original_image.size
|
||||
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)
|
||||
|
||||
return result_image
|
||||
|
@ -30,11 +35,12 @@ class GradationFilter:
|
|||
|
||||
@staticmethod
|
||||
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:
|
||||
image_path = "Gradation/60D2151A-A12A-4F89-9D79-D7FD5DBEA4C4.png"
|
||||
|
||||
|
||||
gradation_filter = GradationFilter(image_path)
|
||||
|
||||
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.show()
|
||||
|
||||
except IOError:
|
||||
except OSError:
|
||||
print("Error: Not a PNG file.")
|
||||
except Exception as e:
|
||||
print(f"An unexpected error occurred: {e}")
|
||||
|
|
Loading…
Reference in New Issue
Block a user