From 82e9977ddb6de7b27c601399fd609e86d0563f47 Mon Sep 17 00:00:00 2001 From: Tharindu N <40334396+truethari@users.noreply.github.com> Date: Sat, 3 Apr 2021 11:05:50 +0530 Subject: [PATCH 1/6] added bg_colour and font_colour features --- thumb_gen/application.py | 44 ++++++++++++++++++++++++++++++++-------- thumb_gen/config.py | 14 +++++++++++-- thumb_gen/options.py | 11 +++++++--- thumb_gen/version.py | 2 +- thumb_gen/viewer.py | 21 +++++++++++++++++-- thumb_gen/worker.py | 20 ++++++++++-------- 6 files changed, 87 insertions(+), 25 deletions(-) diff --git a/thumb_gen/application.py b/thumb_gen/application.py index c2750ac..9124148 100644 --- a/thumb_gen/application.py +++ b/thumb_gen/application.py @@ -1,5 +1,6 @@ import os import re +import sys import datetime from ffmpy import FFmpeg @@ -7,6 +8,7 @@ from PIL import Image from PIL import ImageFont from PIL import ImageDraw +from PIL import ImageColor from .config import read_config from .utils import listToString, video_info, get_file_size, convert_unit, packagePath @@ -79,7 +81,7 @@ def lining(text, font, font_size, image_width): return lines -def imageText(video_path, secure_tmp, bg_width, bg_height, custom_text, font_dir, font_size): +def imageText(video_path, secure_tmp, bg_width, bg_height, custom_text, font_dir, font_size, bg_colour, font_colour): if font_dir == '': font_name = read_config('font') if font_name == '': @@ -97,6 +99,12 @@ def imageText(video_path, secure_tmp, bg_width, bg_height, custom_text, font_dir elif custom_text == 'False': custom_text = '' + if bg_colour == '': + bg_colour = read_config('bg_colour') + + if font_colour == '': + font_colour = read_config('font_colour') + filename = re.split(pattern = r"[/\\]", string = video_path) filename = filename[-1] @@ -183,7 +191,25 @@ def imageText(video_path, secure_tmp, bg_width, bg_height, custom_text, font_dir bg_new_height = text_area_height + bg_height - img = Image.new('RGB', (bg_width, bg_new_height), color = 'white') + try: + bg_colour = ImageColor.getrgb(bg_colour) + except ValueError: + bg_colour = bg_colour + print("ValueError: unknown color specifier: {}".format(bg_colour)) + print("This can be fixed by changing the configurations.\n" \ + "Ex: Background colour = 'white' / Background colour = '#ffffff'") + sys.exit() + + try: + font_colour = ImageColor.getrgb(font_colour) + except ValueError: + font_colour = font_colour + print("ValueError: unknown color specifier: {}".format(font_colour)) + print("This can be fixed by changing the configurations.\n" \ + "Ex: Font colour = 'black' / Font colour = '#ffffff'") + sys.exit() + + img = Image.new('RGB', (bg_width, bg_new_height), bg_colour) img.save(os.path.join(secure_tmp, 'bg.png')) background = Image.open(os.path.join(secure_tmp, 'bg.png')) @@ -211,21 +237,21 @@ def imageText(video_path, secure_tmp, bg_width, bg_height, custom_text, font_dir for lines in info_filename_line['line{}'.format(rounds)]: if lines != []: font_height = font_info(info_filename, font_name, font_size)[1] - draw.text((x, y), lines, 'black', font=font) + draw.text((x, y), lines, font_colour, font=font) y = y + font_height font_height = font_info(info_filesize, font_name, font_size)[1] #line2 - draw.text((x, y), info_line2, 'black', font=font) + draw.text((x, y), info_line2, font_colour, font=font) y = y + 5 + font_height #line3 - draw.text((x, y), info_line3, 'black', font=font) + draw.text((x, y), info_line3, font_colour, font=font) y = y + 5 + font_height #line4 - draw.text((x, y), info_line4, 'black', font=font) + draw.text((x, y), info_line4, font_colour, font=font) y = y + 5 + font_height rounds = 0 @@ -236,7 +262,7 @@ def imageText(video_path, secure_tmp, bg_width, bg_height, custom_text, font_dir for lines in text_lines['line{}'.format(rounds)]: if lines != []: font_height = font_info(lines, font_name, font_size)[1] - draw.text((x, y), lines, 'black', font=font) + draw.text((x, y), lines, font_colour, font=font) y = y + font_height y = y + 5 @@ -277,7 +303,7 @@ def resize(screenshot_folder, resize_folder): return True -def thumb(video_path, output_folder, resize_folder, secure_temp, custom_text, font_dir, font_size): +def thumb(video_path, output_folder, resize_folder, secure_temp, custom_text, font_dir, font_size, bg_colour, font_colour): for img in os.listdir(resize_folder): image = Image.open(os.path.join(resize_folder, img)) r_new_width, new_height = image.size @@ -292,7 +318,7 @@ def thumb(video_path, output_folder, resize_folder, secure_temp, custom_text, fo bg_new_width = int((r_new_width * 3) + 20) bg_new_height = int((new_height * img_rows) + ((5 * img_rows) + 5)) - y = imageText(video_path, secure_temp, bg_new_width, bg_new_height, custom_text, font_dir, font_size) + y = imageText(video_path, secure_temp, bg_new_width, bg_new_height, custom_text, font_dir, font_size, bg_colour, font_colour) backgroud = Image.open(os.path.join(secure_temp, 'bg.png')) diff --git a/thumb_gen/config.py b/thumb_gen/config.py index 195dee9..f2abf26 100644 --- a/thumb_gen/config.py +++ b/thumb_gen/config.py @@ -4,7 +4,7 @@ from .utils import get_datadir, CheckIfFileExists from .version import config_version -def create_config(IMAGES=12, IMAGE_QUALITY=80, FONT='', FONT_SIZE=30, CUSTOM_TEXT=''): +def create_config(IMAGES=12, IMAGE_QUALITY=80, FONT='', FONT_SIZE=30, CUSTOM_TEXT='', BG_COLOUR='white', FONT_COLOUR='black'): my_datadir = get_datadir() / "thumb-gen" try: @@ -16,7 +16,7 @@ def create_config(IMAGES=12, IMAGE_QUALITY=80, FONT='', FONT_SIZE=30, CUSTOM_TEX finally: configfile_path = os.path.join(str(my_datadir), "config.ini") config_object = configparser.ConfigParser() - config_object["DEFAULT"] = {"images": IMAGES, "image_quality": IMAGE_QUALITY, "font":FONT, "font_size":FONT_SIZE, "custom_text":CUSTOM_TEXT} + config_object["DEFAULT"] = {"images": IMAGES, "image_quality": IMAGE_QUALITY, "font":FONT, "font_size":FONT_SIZE, "custom_text":CUSTOM_TEXT, "bg_colour":BG_COLOUR, "font_colour":FONT_COLOUR} config_object["VERSION"] = {"config_version": config_version} with open(configfile_path, 'w') as conf: config_object.write(conf) @@ -49,6 +49,12 @@ def modify_config(options, value): else: userinfo["custom_text"] = str(value) + elif options == "bg_colour": + userinfo["bg_colour"] = str(value) + + elif options == "font_colour": + userinfo["font_colour"] = str(value) + with open(configfile_path, 'w') as conf: config_object.write(conf) @@ -96,6 +102,10 @@ def read_config(option): return int(default['font_size']) elif option == 'custom_text': return str(default['custom_text']) + elif option == 'bg_colour': + return str(default['bg_colour']) + elif option == 'font_colour': + return str(default['font_colour']) loop = False except KeyError: diff --git a/thumb_gen/options.py b/thumb_gen/options.py index 5834175..0abae21 100644 --- a/thumb_gen/options.py +++ b/thumb_gen/options.py @@ -41,8 +41,7 @@ def parseOpts(argument_list): sys.exit() elif opt in ("-c", "--config"): - conf_images, conf_image_quality, conf_font, conf_font_size, conf_custom_text = configurations() - + conf_images, conf_image_quality, conf_font, conf_font_size, conf_custom_text, conf_bg_colour, conf_font_colour = configurations() if conf_images != 0: modify_config('images', conf_images) @@ -55,9 +54,15 @@ def parseOpts(argument_list): if conf_font_size != 0: modify_config('font_size', conf_font_size) - if conf_custom_text != 0: + if conf_custom_text != '': modify_config('custom_text', conf_custom_text) + if conf_bg_colour != '': + modify_config('bg_colour', conf_bg_colour) + + if conf_font_colour != '': + modify_config('font_colour', conf_font_colour) + sys.exit() def begin(args='', opt=''): diff --git a/thumb_gen/version.py b/thumb_gen/version.py index e48aa39..e10df61 100644 --- a/thumb_gen/version.py +++ b/thumb_gen/version.py @@ -1,2 +1,2 @@ __version__ = "1.0.4" -config_version = "2021.03.25" \ No newline at end of file +config_version = "2021.04.03" \ No newline at end of file diff --git a/thumb_gen/viewer.py b/thumb_gen/viewer.py index 2cfa225..3ee4286 100644 --- a/thumb_gen/viewer.py +++ b/thumb_gen/viewer.py @@ -36,7 +36,20 @@ def helps(): def configurations(): print("Configurations\n") - print("Images = {}\nThumbnail Quality = {}\n".format(read_config('images'), read_config('image_quality'))) + print("Images = {}\n" \ + "Thumbnail Quality = {}\n" \ + "Font = {}\n" \ + "Font Size = {}\n" \ + "Custom Text = {}\n" \ + "Background Colour = {}\n" \ + "Font Colour = {}\n" \ + .format(read_config('images'), \ + read_config('image_quality'), \ + read_config('font'), \ + read_config('font_size'), \ + read_config('custom_text'), \ + read_config('bg_colour'), \ + read_config('font_colour'))) loop = True while loop: @@ -87,16 +100,20 @@ def configurations(): print("Enter number between 10 - 100!") except ValueError: print("Invalid input! Please enter a valid number.") + print("Input 'clear' or '000' to clear custom text") custom_text = str(input("Custom text: ") or '') + bg_colour = str(input("Background Colour: ") or '') + font_colour = str(input("Font Colour: ") or '') + except KeyboardInterrupt: loop = False sys.exit() loop = False - return images, image_quality, font_path, font_size, custom_text + return images, image_quality, font_path, font_size, custom_text, bg_colour, font_colour def print_process(name): oss = check_os() diff --git a/thumb_gen/worker.py b/thumb_gen/worker.py index e4a13df..f929e53 100644 --- a/thumb_gen/worker.py +++ b/thumb_gen/worker.py @@ -7,14 +7,8 @@ from .utils import listToString class Generator: - def __init__(self, video_path, output_path='', custom_text='True', font_dir='', font_size=0): + def __init__(self, video_path, output_path='', custom_text='True', font_dir='', font_size=0, bg_colour='', font_colour=''): self.video_path = video_path - self.font_dir = font_dir - - if isinstance(font_size, int): - self.font_size = font_size - elif isinstance(font_size, str): - raise ValueError("Font size must be an integer") if output_path == '': self.output_path = self.video_path[:-4] @@ -26,6 +20,16 @@ def __init__(self, video_path, output_path='', custom_text='True', font_dir='', self.output_folder = self.output_path self.custom_text = str(custom_text) + self.font_dir = font_dir + + if isinstance(font_size, int): + self.font_size = font_size + elif isinstance(font_size, str): + raise ValueError("Font size must be an integer") + + self.bg_colour = bg_colour + self.font_colour = font_colour + self.temp_dir = tempfile.TemporaryDirectory() self.secure_temp = self.temp_dir.name self.screenshot_folder = os.path.join(self.secure_temp, 'screenshots') @@ -37,7 +41,7 @@ def run(self): print_process(self.video_path) screenshots(self.video_path, self.screenshot_folder) resize(self.screenshot_folder, self.resize_folder) - thumb_out = thumb(self.video_path, self.output_path, self.resize_folder, self.secure_temp, self.custom_text, self.font_dir, self.font_size) + thumb_out = thumb(self.video_path, self.output_path, self.resize_folder, self.secure_temp, self.custom_text, self.font_dir, self.font_size, self.bg_colour, self.font_colour) if thumb_out: print_success(self.output_folder) From 702bc5311fbfda7d04480991d6e6b7210a66fe83 Mon Sep 17 00:00:00 2001 From: Tharindu N <40334396+truethari@users.noreply.github.com> Date: Sat, 3 Apr 2021 17:08:33 +0530 Subject: [PATCH 2/6] check if the color is valid --- thumb_gen/viewer.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/thumb_gen/viewer.py b/thumb_gen/viewer.py index 3ee4286..779b131 100644 --- a/thumb_gen/viewer.py +++ b/thumb_gen/viewer.py @@ -3,6 +3,7 @@ from .config import read_config from .utils import CheckIfFileExists, check_os from datetime import datetime +from PIL import ImageColor now = datetime.now() current_time = now.strftime("%H:%M:%S") @@ -104,8 +105,31 @@ def configurations(): print("Input 'clear' or '000' to clear custom text") custom_text = str(input("Custom text: ") or '') - bg_colour = str(input("Background Colour: ") or '') - font_colour = str(input("Font Colour: ") or '') + loop8 = True + while loop8: + try: + bg_colour = str(input("Background Colour: ") or '') + if bg_colour == '': + pass + else: + bg_colour = ImageColor.getrgb(bg_colour) + except ValueError: + print("Color not recognized: {}. Enter a valid colour!".format(bg_colour)) + else: + loop8 = False + + loop9 = True + while loop9: + try: + font_colour = str(input("Font Colour: ") or '') + if font_colour == '': + pass + else: + font_colour = ImageColor.getrgb(font_colour) + except ValueError: + print("Color not recognized: {}. Enter a valid colour!".format(font_colour)) + else: + loop9 = True except KeyboardInterrupt: loop = False From 1241c76349de6c935f4d5e6a7e3d93c869892d43 Mon Sep 17 00:00:00 2001 From: Tharindu N <40334396+truethari@users.noreply.github.com> Date: Sat, 3 Apr 2021 17:20:35 +0530 Subject: [PATCH 3/6] cleaned while loops --- thumb_gen/viewer.py | 52 ++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/thumb_gen/viewer.py b/thumb_gen/viewer.py index 779b131..8ce8a3f 100644 --- a/thumb_gen/viewer.py +++ b/thumb_gen/viewer.py @@ -52,90 +52,80 @@ def configurations(): read_config('bg_colour'), \ read_config('font_colour'))) - loop = True - while loop: + while True: try: - loop2 = True - while loop2: + while True: print("If you do not want to change the values, leave the input blank and press Enter.\n") print("CTRL + C to exit.") try: images = int(input("Images: ") or 0) - loop2 = False + break except ValueError: print("Invalid input! Please enter a valid number.") - loop3 = True - while loop3: + while True: try: - loop4 = True - while loop4: + while True: image_quality = int(input("Thumbnail Quality (10 - 100): ") or 0) if 101 > image_quality > 9 or image_quality == 0: - loop4 = False - loop3 = False + break else: print("Enter number between 10 - 100!") + break except ValueError: print("Invalid input! Please enter a valid number.") - loop5 = True - while loop5: + while True: font_path = str(input("Font Path: ") or '0') font_path_status = CheckIfFileExists(font_path) if font_path_status or font_path == '0': - loop5 = False + break else: print("No font file found. Check the path and re-enter it") - loop6 = True - while loop6: + while True: try: - loop7 = True - while loop7: + while True: font_size = int(input("Font Size (10 - 100): ") or 0) if 9 < font_size < 101 or font_size == 0: - loop7 = False - loop6 = False + break else: print("Enter number between 10 - 100!") + break except ValueError: print("Invalid input! Please enter a valid number.") print("Input 'clear' or '000' to clear custom text") custom_text = str(input("Custom text: ") or '') - loop8 = True - while loop8: + while True: try: bg_colour = str(input("Background Colour: ") or '') if bg_colour == '': pass else: - bg_colour = ImageColor.getrgb(bg_colour) + ImageColor.getrgb(bg_colour) except ValueError: print("Color not recognized: {}. Enter a valid colour!".format(bg_colour)) else: - loop8 = False + break - loop9 = True - while loop9: + while True: try: font_colour = str(input("Font Colour: ") or '') if font_colour == '': pass else: - font_colour = ImageColor.getrgb(font_colour) + ImageColor.getrgb(font_colour) except ValueError: print("Color not recognized: {}. Enter a valid colour!".format(font_colour)) else: - loop9 = True + break except KeyboardInterrupt: - loop = False - sys.exit() + sys.exit('\n') - loop = False + break return images, image_quality, font_path, font_size, custom_text, bg_colour, font_colour From 800500fc9afe967d9ad5a125ba853e728288e400 Mon Sep 17 00:00:00 2001 From: Tharindu N <40334396+truethari@users.noreply.github.com> Date: Sat, 3 Apr 2021 17:50:32 +0530 Subject: [PATCH 4/6] updated README files --- README.md | 18 ++++++++---------- README.rst | 17 +++++++---------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f9e9180..071e3bf 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,13 @@ You can use pip: ## Configurations -(These may change during the update) - - The number of screen images that should be included in the final thumbnail image - - Thumbnail image quality - - Font type in the video info panel. You can add a file path of a font file (.ttf) to this - - Font size in the video info panel - - Custom text in the video info panel +- Background color of the thumbnail (Hex codes are also supported) +- Font colour of the thumbnail (Hex codes are also supported) Download font files : [FontSquirrel](https://www.fontsquirrel.com/) @@ -54,6 +50,8 @@ IMAGE_QUALITY = 80 FONT = FONT_SIZE = 30 CUSTOM_TEXT = +BG_COLOUR = white +FONT_COLOUR = black ``` ## Usage @@ -95,15 +93,15 @@ CUSTOM_TEXT = ### Python -- If you don't set an output folder, thumbnail images will be saved in the video folder (video_path). -- If you don't need a custom text and custom font file (including font size) and you have already set these for the configuration file (using console or defaults), it will be added automatically. To avoid this set the `custom_text` value to `False` and add a custom font file location. +- If you don't set an output folder, thumbnail images will be saved in the video folder (video_path). +- If you don't need a custom text and custom font file (including font size) and you have already set these for the configuration file (using console or defaults), it will be added automatically. To avoid this set the `custom_text` value to `False` and add a custom font file location. #### Example 1 ``` python from thumb_gen.worker import Generator -#video_path, output_path='', custom_text=True, font_dir='', font_size= +#video_path, output_path='', custom_text=True, font_dir='', font_size=0, bg_colour='', font_colour='' app = Generator("C:/input/video.mp4", "C:/output/", "www.example.com", "C:/Windows/Fonts/Arial.ttf", 30) app.run() ``` @@ -117,6 +115,6 @@ from thumb_gen.worker import Generator folder = 'C:/input' for video in os.listdir(folder): if video.endswith('.mp4') or video.endswith('.mkv'): - app = Generator(os.path.join(folder, video), custom_text=False, font_dir="C:/Project/font.ttf", font_size=25) + app = Generator(os.path.join(folder, video), custom_text=False, font_dir="C:/Project/font.ttf", font_size=25, bg_colour='blue', font_colour='red') app.run() ``` diff --git a/README.rst b/README.rst index 2324044..e74bf8c 100644 --- a/README.rst +++ b/README.rst @@ -30,17 +30,13 @@ You can use pip: Configurations -------------- -(These may change during the update) - - The number of screen images that should be included in the final thumbnail image. - - Thumbnail image quality - - Font type in the video info panel. You can add a file path of a font file (.ttf) to this. - - Font size in the video info panel - - Custom text in the video info panel +- Background color of the thumbnail (Hex codes are also supported) +- Font colour of the thumbnail (Hex codes are also supported) Download font files : `FontSquirrel `_ @@ -63,6 +59,8 @@ By program default: FONT = FONT_SIZE = 30 CUSTOM_TEXT = + BG_COLOUR = white + FONT_COLOUR = black ----- Usage @@ -109,7 +107,6 @@ Python ====== - If you don't set an output folder, thumbnail images will be saved in the video folder (video_path). - - If you don't need a custom text and custom font file (including font size) and you have already set these for the configuration file (using console or defaults), it will be added automatically. To avoid this set the `custom_text` value to `False` and add a custom font file location. Example 1 @@ -131,6 +128,6 @@ Example 2 folder = 'C:/input' for video in os.listdir(folder): - if video.endswith('.mp4') or video.endswith('.mkv'): - app = Generator(os.path.join(folder, video), custom_text=False) - app.run() + if video.endswith('.mp4') or video.endswith('.mkv'): + app = Generator(os.path.join(folder, video), custom_text=False, font_dir="C:/Project/font.ttf", font_size=25, bg_colour='blue', font_colour='red') + app.run() From 3a528199dbfc0d1bed853693d72797ce566835b2 Mon Sep 17 00:00:00 2001 From: Tharindu N <40334396+truethari@users.noreply.github.com> Date: Sat, 3 Apr 2021 18:04:03 +0530 Subject: [PATCH 5/6] removed .travis.yml and added requirements.txt --- .github/workflows/thumb-gen.yml | 2 +- .travis.yml | 16 ---------------- requirements.txt | 3 +++ 3 files changed, 4 insertions(+), 17 deletions(-) delete mode 100644 .travis.yml create mode 100644 requirements.txt diff --git a/.github/workflows/thumb-gen.yml b/.github/workflows/thumb-gen.yml index 10a6085..31acc43 100644 --- a/.github/workflows/thumb-gen.yml +++ b/.github/workflows/thumb-gen.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install pytest Pillow get-video-properties ffmpy ffmpeg-python + python -m pip install pytest Pillow get-video-properties ffmpy sudo wget -P /home/ "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4" sudo apt-get install ffmpeg - name: Test with pytest diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6788022..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: python - -python: "3.6" - -before_install: - - sudo wget -P /home/ "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4" - - sudo apt-get install ffmpeg - -install: - - pip install Pillow - - pip install get-video-properties - - pip install ffmpy - - pip install ffmpeg-python - -script: - - pytest tests diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..092470f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +ffmpy +get_video_properties +Pillow From 1d369981698259aac0433f6bd1339d3a38969413 Mon Sep 17 00:00:00 2001 From: Tharindu N <40334396+truethari@users.noreply.github.com> Date: Sat, 3 Apr 2021 18:05:15 +0530 Subject: [PATCH 6/6] version = 1.0.5 --- thumb_gen/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thumb_gen/version.py b/thumb_gen/version.py index e10df61..6a9f5af 100644 --- a/thumb_gen/version.py +++ b/thumb_gen/version.py @@ -1,2 +1,2 @@ -__version__ = "1.0.4" +__version__ = "1.0.5" config_version = "2021.04.03" \ No newline at end of file