Skip to content

Instantly share code, notes, and snippets.

@oiehot
Created December 16, 2018 04:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oiehot/9758d78c01b60f95134a8c33642b81b3 to your computer and use it in GitHub Desktop.
Save oiehot/9758d78c01b60f95134a8c33642b81b3 to your computer and use it in GitHub Desktop.
copyrighter.py
import os
import sys
import re
from PIL import Image, ImageDraw, ImageFont
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtCore import QEvent
from datetime import datetime
from os.path import getmtime
DEFAULT_ARTIST = "Taewoo Lee (anyzac.ltw@gmail.com)"
DEFAULT_COPYRIGHT = "(C) AZ/GG/SKB/DW"
DEFAULT_COMMENT = "No comment.\nAll copyrights are auto-generated."
DEFAULT_FONT = './arial.ttf'
TITLE_FONT_SIZE = 0.02
COPYRIGHT_FONT_SIZE = 0.01
COMMENT_FONT_SIZE = 0.01
MARGIN_RATE = 0.05 # ex) height * 0.05
# 파일명에 이미 날짜가 들어가 있는 경우의 처리
def filename_has_date(filePath):
'파일명 앞에 yyymmdd 형태의 날짜가 적혀져 있으면 True를 리턴한다'
yyyymmdd_re = re.compile('[0-9]{8}_.*')
filename = os.path.splitext(os.path.basename(filePath))[0]
if yyyymmdd_re.match(filename):
return True
else:
return False
def stamp(filePath, artist, comment, copyright, logger):
try:
img = Image.open(filePath)
except:
logger.log('%s 는 이미지 파일이 아닙니다.' % filePath)
return
# 배경색을 얻는다.
bg_color = img.getpixel( (0,0) )
fg_color = (255-bg_color[0], 255-bg_color[1], 255-bg_color[2], 255)
_orgn_bbox = img.getbbox()
_orgn_width = _orgn_bbox[2]
_orgn_height = _orgn_bbox[3]
# 여백 계산
margin_v = round(_orgn_height * MARGIN_RATE)
margin = {
'top': margin_v,
'left': 0,
'right': 0,
'bottom': round(margin_v * 0.5)
}
# 여백을 포함하여 Crop 하기
crop_bbox = (
_orgn_bbox[0] - margin['left'],
_orgn_bbox[1] - margin['top'],
_orgn_bbox[2] + margin['right'],
_orgn_bbox[3] + margin['bottom']
)
img = img.crop(crop_bbox)
# Crop 이후
bbox = img.getbbox()
# fix bbox !!
bbox = (bbox[0], bbox[1]-margin['top'], bbox[2], bbox[3]+margin['bottom'])
top_area = ( 0, 0, bbox[2], margin['top'] )
bottom_area = ( 0, bbox[3] - margin['bottom'], bbox[2], bbox[3] )
draw = ImageDraw.Draw(img)
draw.rectangle(top_area, outline=None, fill=bg_color)
draw.rectangle(bottom_area, outline=None, fill=bg_color)
# 폰트 사이즈 결정
title_fnt_size = round(min(_orgn_width, _orgn_height) * TITLE_FONT_SIZE)
title_fnt = ImageFont.truetype(DEFAULT_FONT, title_fnt_size)
copyright_fnt_size = round(min(_orgn_width, _orgn_height) * COPYRIGHT_FONT_SIZE)
copyright_fnt = ImageFont.truetype(DEFAULT_FONT, copyright_fnt_size)
comment_fnt_size = round(min(_orgn_width, _orgn_height) * COMMENT_FONT_SIZE)
comment_fnt = ImageFont.truetype(DEFAULT_FONT, comment_fnt_size)
# 타이틀 그리기
title_text = ''
if filename_has_date(filePath):
title_text = '[%s]' % os.path.splitext(os.path.basename(filePath))[0]
else:
yyyymmdd = datetime.fromtimestamp(getmtime(filePath)).strftime('%Y%m%d')
filename = os.path.splitext( os.path.basename(filePath) )[0]
title_text = '[%s_%s]' % (yyyymmdd, filename)
draw.text((50,50), title_text, font=title_fnt, fill=fg_color )
# 카피 라이트 그리기
copyright_text = copyright
copyright_w, copyright_h = draw.textsize(copyright_text, copyright_fnt)
copyright_x = round(_orgn_width/2 - copyright_w/2)
copyright_y = bbox[3] - margin['bottom'] + round(copyright_h/2)
draw.text( (copyright_x, copyright_y), copyright_text, font=copyright_fnt, fill=fg_color )
# 추가 정보 그리기
add_text = 'Artist: %s\nComment:\n%s' % (artist, comment)
add_text_w, add_text_h = draw.textsize(add_text, comment_fnt)
add_text_x = bbox[2] - add_text_w - 50
add_text_y = bbox[0] + 50
draw.text( (add_text_x, add_text_y), add_text, font=comment_fnt, fill=fg_color )
# 저장하기
pre, ext = os.path.splitext(filePath)
output = pre + '_Sealed.png'
try:
img.save(output)
except:
logger.log('%s 저장에 실패했습니다.' % filePath)
return
logger.log('%s 성공.' % filePath)
class FileListView(QListWidget):
def __init__(self, parent):
super().__init__(parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
event.accept()
def dropEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
for url in event.mimeData().urls():
filePath = str(url.toLocalFile())
self.addItem(filePath)
else:
event.ignore()
def removeSelected(self):
for item in self.selectedItems():
n = self.row(item)
self.takeItem(n)
def getFileList(self):
result = []
max = self.count()
for i in range(max):
item = self.item(i)
result.append(item.text())
return result
class CopyrighterWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Copyrighter")
self.setGeometry(300, 300, 900, 450)
self.hLayout = QHBoxLayout()
self.setLayout(self.hLayout)
# Left VLayout
self.vLayout = QVBoxLayout()
self.hLayout.addLayout(self.vLayout)
# Right VLayout
self.vLayoutR = QVBoxLayout()
self.hLayout.addLayout(self.vLayoutR)
self.logForm = QPlainTextEdit('', self)
self.vLayoutR.addWidget(self.logForm)
# Files list
self.fileListView = FileListView(self)
self.vLayout.addWidget(self.fileListView)
# Remove File Button
self.removeFileButton = QPushButton("Remove", self)
self.removeFileButton.clicked.connect(self.fileListView.removeSelected)
self.vLayout.addWidget(self.removeFileButton)
# Grid Layout
self.gridLayout = QGridLayout()
self.vLayout.addLayout(self.gridLayout)
# Title Form
self.titleCheckbox = QCheckBox("Title", self)
self.titleCheckbox.setChecked(True)
# self.titleForm = QLineEdit("", self)
self.gridLayout.addWidget(self.titleCheckbox,0,0)
# self.gridLayout.addWidget(self.titleForm,0,1)
# Artist Form
self.artistCheckbox = QCheckBox("Artist", self)
self.artistCheckbox.setChecked(True)
self.artistForm = QLineEdit(DEFAULT_ARTIST)
self.gridLayout.addWidget(self.artistCheckbox,1,0)
self.gridLayout.addWidget(self.artistForm,1,1)
# Copyright Form
self.copyrightCheckbox = QCheckBox("Copyright", self)
self.copyrightCheckbox.setChecked(True)
self.copyrightForm = QLineEdit(DEFAULT_COPYRIGHT, self)
self.gridLayout.addWidget(self.copyrightCheckbox,2,0)
self.gridLayout.addWidget(self.copyrightForm,2,1)
# Comment Form
self.commentCheckbox = QCheckBox("Comment", self)
self.commentCheckbox.setChecked(True)
# self.commentForm = QLineEdit(DEFAULT_COMMENT, self)
self.commentForm = QPlainTextEdit(DEFAULT_COMMENT, self)
self.gridLayout.addWidget(self.commentCheckbox,3,0)
self.gridLayout.addWidget(self.commentForm,3,1)
# Start Button
self.startButton = QPushButton("Start", self)
self.startButton.clicked.connect(self.startButtonClicked)
self.vLayout.addWidget(self.startButton)
def drawTitleCheckboxChanged(self):
if self.drawTitleCheckbox.isChecked() == True:
QMessageBox.about(self, "Info", "Checked")
def startButtonClicked(self):
self.run()
def log(self, text):
self.logForm.insertPlainText(text + '\n')
def run(self):
# self.title = filename
artist = self.artistForm.text()
comment = self.commentForm.toPlainText()
copyright = self.copyrightForm.text()
files = self.fileListView.getFileList()
for file in files:
stamp(file, artist, comment, copyright, self)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = CopyrighterWindow()
win.show()
app.exec_()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment