diff --git a/sigal/gallery.py b/sigal/gallery.py index 50a2431..e83c156 100644 --- a/sigal/gallery.py +++ b/sigal/gallery.py @@ -36,9 +36,10 @@ from multiprocessing import Pool, cpu_count from os.path import join, normpath from PIL import Image as PILImage -from . import compat, image, video +from . import compat +from .image import process_image from .log import colored, BLUE -from .settings import get_thumb +from .video import process_video from .writer import Writer DESCRIPTION_FILE = "index.md" @@ -167,7 +168,6 @@ class PathsDb(object): class Gallery(object): - "Prepare images" def __init__(self, settings, force=False, theme=None, ncpu=None): self.settings = settings @@ -307,46 +307,6 @@ def worker(args): return 'KeyboardException' -def process_image(filepath, outpath, settings): - """Process one image: resize, create thumbnail.""" - - filename = os.path.split(filepath)[1] - outname = join(outpath, filename) - ext = os.path.splitext(filename) - - if ext in ['.jpg', '.jpeg', '.JPG', '.JPEG']: - options = settings['jpg_options'] - elif ext == '.png': - options = {'optimize': True} - else: - options = {} - - image.generate_image(filepath, outname, settings, options=options) - - if settings['make_thumbs']: - thumb_name = join(outpath, get_thumb(settings, filename)) - image.generate_thumbnail( - outname, thumb_name, settings['thumb_size'], - fit=settings['thumb_fit'], options=options) - - -def process_video(filepath, outpath, settings): - """Process one image: resize, create thumbnail.""" - - filename = os.path.split(filepath)[1] - base, ext = os.path.splitext(filename) - outname = join(outpath, base + '.webm') - - video.generate_video(filepath, outname, settings['video_size'], - settings['webm_options']) - - if settings['make_thumbs']: - thumb_name = join(outpath, get_thumb(settings, filename)) - video.generate_thumbnail( - outname, thumb_name, settings['thumb_size'], - fit=settings['thumb_fit'], options=settings['jpg_options']) - - def copy(src, dst, symlink=False): """Copy or symlink the file.""" func = os.symlink if symlink else shutil.copy2 diff --git a/sigal/image.py b/sigal/image.py index eb580b5..6310662 100644 --- a/sigal/image.py +++ b/sigal/image.py @@ -30,6 +30,7 @@ # and partially modified. The code in question is licensed under MIT license. import logging +import os import pilkit.processors import sys @@ -41,6 +42,7 @@ from pilkit.utils import save_image from datetime import datetime from . import compat +from .settings import get_thumb def _has_exif_tags(img): @@ -113,6 +115,28 @@ def generate_thumbnail(source, outname, box, fit=True, options=None): save_image(img, outname, outformat, options=options, autoconvert=True) +def process_image(filepath, outpath, settings): + """Process one image: resize, create thumbnail.""" + + filename = os.path.split(filepath)[1] + outname = os.path.join(outpath, filename) + ext = os.path.splitext(filename) + + if ext in ['.jpg', '.jpeg', '.JPG', '.JPEG']: + options = settings['jpg_options'] + elif ext == '.png': + options = {'optimize': True} + else: + options = {} + + generate_image(filepath, outname, settings, options=options) + + if settings['make_thumbs']: + thumb_name = os.path.join(outpath, get_thumb(settings, filename)) + generate_thumbnail(outname, thumb_name, settings['thumb_size'], + fit=settings['thumb_fit'], options=options) + + def add_copyright(img, text): """Add a copyright to the image.""" diff --git a/sigal/video.py b/sigal/video.py index 29e547c..f217b9a 100644 --- a/sigal/video.py +++ b/sigal/video.py @@ -25,16 +25,15 @@ import subprocess import os import re import shutil -import sigal.image -from . import compat +from . import compat, image +from .settings import get_thumb -def vid_size(source): +def video_size(source): """Returns the dimensions of the video""" pattern = re.compile(r'Stream.*Video.* ([0-9]+)x([0-9]+)') - p = subprocess.Popen(['ffmpeg', '-i', source], - stdout=subprocess.PIPE, + p = subprocess.Popen(['ffmpeg', '-i', source], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() @@ -46,20 +45,20 @@ def vid_size(source): x, y = int(match.groups()[0]), int(match.groups()[1]) else: x = y = 0 - return (x, y) + return x, y def generate_video(source, outname, size, options={}): """Video processor - :param source: path to an image + :param source: path to a video :param outname: name of the generated video :param options: array of options passed to ffmpeg """ # Don't transcode if source is in the required format and # has fitting datedimensions, copy instead. - w_src, h_src = vid_size(source) + w_src, h_src = video_size(source) w_dst, h_dst = size base, src_ext = os.path.splitext(source) base, dst_ext = os.path.splitext(outname) @@ -84,22 +83,39 @@ def generate_video(source, outname, size, options={}): # http://ffmpeg.org/trac/ffmpeg/wiki/vpxEncodingGuide with open("/dev/null") as devnull: subprocess.call(['ffmpeg', '-i', source, '-y', - '-crf', options.get('crf', '10'), - '-b:v', options.get('bitrate', '1.6M'), - '-qmin', options.get('qmin', '4'), - '-qmax', options.get('qmax', '63')] + - resize_opt + [outname], - stderr=devnull) + '-crf', options.get('crf', '10'), + '-b:v', options.get('bitrate', '1.6M'), + '-qmin', options.get('qmin', '4'), + '-qmax', options.get('qmax', '63')] + + resize_opt + [outname], + stderr=devnull) def generate_thumbnail(source, outname, box, fit=True, options=None): - "Create a thumbnail image" + """Create a thumbnail image for the video source, based on ffmpeg.""" # 1) dump an image of the video tmpfile = outname + ".tmp.jpg" with open("/dev/null") as devnull: subprocess.call(['ffmpeg', '-i', source, '-an', '-r', '1', - '-vframes', '1', '-y', tmpfile], stderr=devnull) + '-vframes', '1', '-y', tmpfile], stderr=devnull) # 2) use the generate_thumbnail function from sigal.image - sigal.image.generate_thumbnail(tmpfile, outname, box, fit, options) + image.generate_thumbnail(tmpfile, outname, box, fit, options) # 3) remove the image os.unlink(tmpfile) + + +def process_video(filepath, outpath, settings): + """Process a video: resize, create thumbnail.""" + + filename = os.path.split(filepath)[1] + base, ext = os.path.splitext(filename) + outname = os.path.join(outpath, base + '.webm') + + generate_video(filepath, outname, settings['video_size'], + settings['webm_options']) + + if settings['make_thumbs']: + thumb_name = os.path.join(outpath, get_thumb(settings, filename)) + generate_thumbnail( + outname, thumb_name, settings['thumb_size'], + fit=settings['thumb_fit'], options=settings['jpg_options']) diff --git a/tests/test_video.py b/tests/test_video.py index f3449c4..402bbd9 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -4,7 +4,7 @@ from __future__ import division import os -from sigal.video import vid_size, generate_video +from sigal.video import video_size, generate_video CURRENT_DIR = os.path.dirname(__file__) TEST_VIDEO = 'stallman-software-freedom-day-low.ogv' @@ -18,8 +18,8 @@ def test_generate_video_fit_height(tmpdir): dstfile = str(tmpdir.join(base + '.webm')) generate_video(SRCFILE, dstfile, (50, 100)) - size_src = vid_size(SRCFILE) - size_dst = vid_size(dstfile) + size_src = video_size(SRCFILE) + size_dst = video_size(dstfile) assert size_dst[0] == 50 # less than 2% error on ratio @@ -33,8 +33,8 @@ def test_generate_video_fit_width(tmpdir): dstfile = str(tmpdir.join(base + '.webm')) generate_video(SRCFILE, dstfile, (100, 50)) - size_src = vid_size(SRCFILE) - size_dst = vid_size(dstfile) + size_src = video_size(SRCFILE) + size_dst = video_size(dstfile) assert size_dst[1] == 50 # less than 2% error on ratio @@ -48,7 +48,7 @@ def test_generate_video_dont_enlarge(tmpdir): dstfile = str(tmpdir.join(base + '.webm')) generate_video(SRCFILE, dstfile, (1000, 1000)) - size_src = vid_size(SRCFILE) - size_dst = vid_size(dstfile) + size_src = video_size(SRCFILE) + size_dst = video_size(dstfile) assert size_src == size_dst