autoTrans/base64_to_image.py

122 lines
5.7 KiB
Python

import base64
import pyperclip
import win32clipboard
from io import BytesIO
from PIL import Image
import requests
import numpy as np
import cv2
import time
import random
class base64TOImage:
def __init__(self, app, logger, browser_controller):
self.app = app
self.logger = logger
self.browser_controller = browser_controller # BrowserController 인스턴스를 전달받음
def get_clipboard_data(self):
"""클립보드의 텍스트 데이터를 가져옵니다."""
try:
return pyperclip.paste() # 클립보드의 텍스트 데이터를 가져옴
except Exception as e:
self.logger.debug(f"클립보드 데이터를 가져오는 중 오류 발생: {e}")
return None
def set_image_to_clipboard(self, image):
"""이미지를 클립보드에 넣는 함수 (Windows 전용)"""
output = BytesIO()
image.save(output, "BMP")
data = output.getvalue()[14:] # BMP 헤더 제거
output.close()
# 클립보드에 이미지 데이터 넣기
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
win32clipboard.CloseClipboard()
def base64_to_image(self, base64_data):
"""Base64 데이터를 이미지로 변환하는 함수"""
if base64_data.startswith('data:image'):
header, encoded = base64_data.split(',', 1)
img_data = base64.b64decode(encoded)
image = Image.open(BytesIO(img_data))
return image
else:
self.logger.debug("유효하지 않은 Base64 이미지 데이터입니다.")
return None
def download_image_from_url(self, url, max_retries=3):
"""URL에서 이미지를 다운로드하고 PIL 이미지 객체로 반환"""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"DNT": "1", # Do Not Track 요청 헤더
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Cache-Control": "max-age=0"
}
retries = 0
while retries < max_retries:
try:
self.logger.debug(f"이미지 URL 다운로드 중: {url}")
response = requests.get(url, headers=headers, stream=True)
# 상태 코드가 200이 아니면 재시도
if response.status_code == 200:
# OpenCV로 이미지를 로드하여 변환
image = np.asarray(bytearray(response.content), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
# OpenCV에서 이미지를 PIL로 변환
if image is not None:
pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
return pil_image
else:
self.logger.debug(f"이미지 파일 형식이 올바르지 않습니다. 대상 URL: {url}")
return None
else:
self.logger.debug(f"이미지 로딩 실패, HTTP 상태 코드: {response.status_code}. 재시도 {retries + 1}/{max_retries}")
retries += 1
time.sleep(random.randint(2, 5)) # 2~5초 대기 후 재시도
except Exception as e:
self.logger.debug(f"이미지 로딩 중 오류 발생: {e}. 재시도 {retries + 1}/{max_retries}")
retries += 1
time.sleep(random.randint(2, 5)) # 예외 발생 시 대기 후 재시도
self.logger.debug("이미지 다운로드 최대 재시도 횟수를 초과했습니다.")
return None
def process_clipboard(self, original_url):
"""클립보드의 내용을 처리하고, 필요한 경우 이미지 변환 또는 URL 이미지 복사"""
clipboard_data = self.get_clipboard_data()
if clipboard_data.startswith('data:image'):
# 클립보드에 있는 Base64 데이터를 이미지로 변환
image = self.base64_to_image(clipboard_data)
if image:
self.logger.debug("Base64 이미지 변환 성공, 클립보드에 다시 저장 중...")
self.set_image_to_clipboard(image)
self.logger.debug("이미지가 클립보드에 저장되었습니다.")
else:
self.logger.debug("Base64 이미지 변환 실패.")
elif clipboard_data.strip() == "html > whale-ocr":
# 'html > whale-ocr' 감지 시 원본 이미지 URL에서 이미지를 다운로드하여 클립보드에 복사
if original_url:
image = self.download_image_from_url(original_url)
if image:
self.logger.debug("원본 이미지 다운로드 성공, 클립보드에 다시 저장 중...")
self.set_image_to_clipboard(image)
self.logger.debug("원본 이미지가 클립보드에 저장되었습니다.")
else:
self.logger.debug("원본 이미지 다운로드 실패.")
else:
self.logger.debug("원본 이미지 URL을 찾을 수 없습니다.")
else:
self.logger.debug("클립보드에 Base64 이미지나 'html > whale-ocr' 데이터가 없습니다.")