#!/usr/bin/python3 """Creates the image thumbnails or icons for sledruns to be used in the sledmap or other application. Can be used in a python session or at the command line. usage: createthumbnails.py [-h] {thumbnail,icon} inifile [inifile ...] Creates the image thumbnails or icons for sledruns to be used in the sledmap application. positional arguments: {thumbnail,icon} thumbnails or icons? inifile inifile.ini (See: https://www.winterrodeln.org/trac/wiki/ConfigIni) optional arguments: -h, --help show this help message and exit Command line usage: $ export LANG=de_AT.utf8 $ export LC_CTYPE=de_AT.utf8 $ python createthumbnails.py thumbnail inifile1.ini ... $ # or: $ python createthumbnails.py icon inifile1.ini ... One or more .ini configuration files can be given. At the end, the following entries have to be present: [mysql] host=localhost dbname=philipp_winterrodeln_wiki user_name=philipp_www user_pass=YYYYYY [mediawiki] imagedir=/home/philipp/www/winterrodeln.org/mediawiki/images [sledmap] sledrunimagedir=/home/philipp/www/winterrodeln.org/karte/mediawiki_images sledrunicondir=/home/philipp/www/winterrodeln.org/karte/mediawiki_icons """ import argparse import configparser import os import hashlib import MySQLdb from PIL import Image, ImageFilter def image_to_icon(im, width, height): """The icon will have a size of width times height and contains a centered sub-part of the image.""" if im.size[0] / float(width) > im.size[1] / float(height): # scale image to height im.thumbnail((int(round(im.size[0] * im.size[1] / height)), height), Image.ANTIALIAS) # crop image (left, upper, right (excl), lower (excl)) left = (im.size[0] - width) // 2 im = im.crop((left, 0, left + width, height)) else: # scale image to width im.thumbnail((width, int(round(im.size[1] * im.size[0] / width))), Image.ANTIALIAS) # crop image (left, upper, right (excl), lower (excl)) upper = (im.size[1] - height) // 2 im = im.crop((0, upper, width, upper + height)) # sharpen im = im.filter(ImageFilter.SHARPEN) return im def image_to_thumbnail(im, width, height): """The thumbnail will have a equal or smaller width and height as given. The aspect ratio stays the same.""" im.thumbnail((width, height), Image.ANTIALIAS) im = im.filter(ImageFilter.SHARPEN) return im def update_image_dir(mcon, mediawiki_image_dir, dest_dir, image_function, ignore_existing=True): """Takes all image names from the mysql database (mcon), reads it from mediawiki_image_dir, processed it as given in the image_function and stores it in the dest_dir with the original filename. It does not delete the images that might be present in dest_dir, but overwrites the images with the same filenames. :param mcon: mysql connection :param mediawiki_image_dir: directory of the mediawiki image directory :param dest_dir: output directory :param image_function: python function that takes a PIL Image as parameter and returns a modified PIL Image. :param ignore_existing: True (default) if already existing image file names in the dest dir should be ignored. """ cu = mcon.cursor() sql = "select image from wrsledruncache where image is not null order by image" cu.execute(sql) for image, in cu: image = image.replace(' ', '_') # Create md5sum out of the image filename md5 = hashlib.md5() md5.update(image.encode('UTF8')) hd = md5.hexdigest() # Build source and destination path names source_file = os.path.join(mediawiki_image_dir, hd[0], hd[0:2], image) dest_file = os.path.join(dest_dir, image) if ignore_existing and os.path.exists(dest_file): continue print(('{0}...'.format(image))) im = Image.open(source_file) im = image_function(im) im.save(dest_file, "JPEG") def update_image_dir_by_inifile(inifile, mode): """ Same as update_image_dir but reads the arguments from an .ini file. :param inifile: filename of an .ini file or a list of .ini files. :param mode: 'thumbnail' or 'icon' """ config = configparser.ConfigParser() config.read(inifile) host = config.get('mysql', 'host') dbname = config.get('mysql', 'dbname') user = config.get('mysql', 'user_name') passwd = config.get('mysql', 'user_pass') mcon = MySQLdb.connect(host=host, db=dbname, user=user, passwd=passwd, charset='utf8mb4') mediawiki_image_dir = config.get('mediawiki', 'imagedir') if mode == 'thumbnail': dest_dir = config.get('sledmap', 'sledrunimagedir') image_function = lambda img: image_to_thumbnail(img, 200, 200) elif mode == 'icon': dest_dir = config.get('sledmap', 'sledrunicondir') image_function = lambda img: image_to_icon(img, 80, 80) update_image_dir(mcon, mediawiki_image_dir, dest_dir, image_function) mcon.close() if __name__ == '__main__': parser = argparse.ArgumentParser( description='Creates the image thumbnails or icons for sledruns to be used in the sledmap application.') parser.add_argument('type', choices=['thumbnail', 'icon'], help='thumbnails or icons?') parser.add_argument('inifile', nargs='+', help='inifile.ini, see: https://www.winterrodeln.org/trac/wiki/ConfigIni') args = parser.parse_args() update_image_dir_by_inifile(args.inifile, args.type)