def posterize(files, posterfile=None, background_color="black", margin=5): min_h = max_height(files) min_w = max_width(files) util.logger.debug("Max W x H = %d x %d", min_w, min_h) gap = (min_w * margin) // 100 nb_files = len(files) root = math.sqrt(nb_files) rows = int(round(root)) if rows < root: rows += 1 cols = (nb_files + rows-1) // rows full_w = (cols*min_w) + (cols+1)*gap full_h = (rows*min_h) + (rows+1)*gap util.logger.debug("W x H = %d x %d / Gap = %d / c,r = %d, %d => Full W x H = %d x %d", min_w, min_h, gap, cols, rows, full_w, full_h) bgfile = "white-square.jpg" if background_color == "white" else "black-square.jpg" tmpbg = "bg.tmp.jpg" rescale(bgfile, full_w, full_h, tmpbg) file_list = util.build_ffmpeg_file_list(files) cmplx = util.build_ffmpeg_complex_prep(files) cmplx = cmplx + __build_poster_fcomplex(rows, cols, gap, min_w, min_h, len(files)) posterfile = util.automatic_output_file_name(posterfile, files[0], "poster") util.run_ffmpeg('-i "%s" %s -filter_complex "%s" "%s"' % (tmpbg, file_list, cmplx, posterfile)) util.logger.info("Generated %s", posterfile) util.delete_files(tmpbg) return posterfile
def shake_horizontal(self, nbr_slices = 10 , shake_pct = 3, background_color = "black", out_file = None): w, h = self.get_dimensions() w_jitter = w * shake_pct // 100 slice_height = max(h // nbr_slices, 16) slices = self.slice_horizontal(nbr_slices) tmpbg = get_rectangle(background_color, w + w_jitter, slice_height * len(slices)) filelist = util.build_ffmpeg_file_list(slices) + ' -i "%s"' % tmpbg cmplx = util.build_ffmpeg_complex_prep(slices) step = 0 n_slices = len(slices) cmplx = cmplx + "[%d][pip0]overlay=0:0[step%d]; " % (n_slices, step) first_slice = slices.pop(0) for j in range(n_slices): x = random.randint(1, w_jitter) y = (j+1) * slice_height cmplx = cmplx + "[step%d][pip%d]overlay=%d:%d" % (j, j+1, x, y) if j < n_slices-1: cmplx = cmplx + '[step%d]; ' % (j+1) j = j+1 out_file = util.automatic_output_file_name(out_file, self.filename, "shake") util.run_ffmpeg(' %s -filter_complex "%s" %s' % (filelist, cmplx, out_file)) util.delete_files(*slices, first_slice, tmpbg) return out_file
def blindify(self, out_file = None, **kwargs): nbr_slices = int(kwargs.pop('blinds', 10)) blinds_size_pct = int(kwargs.pop('blinds_ratio', 3)) background_color = kwargs.pop('background_color', 'black') direction = kwargs.pop('direction', 'vertical') w, h = self.get_dimensions() w_gap = w * blinds_size_pct // 100 h_gap = h * blinds_size_pct // 100 if direction == 'horizontal': tmpbg = get_rectangle(background_color, w, (h//nbr_slices*nbr_slices) + h_gap*(nbr_slices-1)) else: tmpbg = get_rectangle(background_color, (w//nbr_slices*nbr_slices) + w_gap*(nbr_slices-1), h) # ffmpeg -i file1.jpg -i file2.jpg -i bg.tmp.jpg \ # -filter_complex "[0]scale=iw:-1:flags=lanczos[pip0]; \ # [1]scale=iw:-1:flags=lanczos[pip1]; \ # [8]scale=iw:-1:flags=lanczos[pip8]; \ # [9][pip0]overlay=204:204[step0] ; \ # [step0][pip1]overlay=2456:204[step1]; \ # [step7][pip8]overlay=4708:3374" outfile.jpg slices = self.slice(nbr_slices, direction) filelist = util.build_ffmpeg_file_list(slices) filelist = filelist + ' -i "%s"' % tmpbg cmplx = util.build_ffmpeg_complex_prep(slices) i = 0 cmplx = '' for slicefile in slices: cmplx = cmplx + "[%d]scale=iw:-1:flags=lanczos[pip%d]; " % (i, i) i = i + 1 step = 0 cmplx = cmplx + "[%d][pip0]overlay=0:0[step%d]; " % (i, step) first_slice = slices.pop(0) j = 0 x = 0 y = 0 for slicefile in slices: if direction == 'horizontal': y = (j+1) * (h // nbr_slices + h_gap) else: x = (j+1) * (w // nbr_slices + w_gap) cmplx = cmplx + "[step%d][pip%d]overlay=%d:%d" % (j, j+1, x, y) if slicefile != slices[len(slices)-1]: cmplx = cmplx + '[step%d]; ' % (j+1) j = j+1 out_file = util.automatic_output_file_name(out_file, self.filename, "blind") util.run_ffmpeg('%s -filter_complex "%s" %s' % (filelist, cmplx, out_file)) util.delete_files(*slices, first_slice, tmpbg)
def stack(file1, file2, direction, out_file = None): util.logger.debug("stack(%s, %s, %s, _)", file1, file2, direction) if not util.is_image_file(file1): raise media.FileTypeError('File %s is not an image file' % file1) if not util.is_image_file(file2): raise media.FileTypeError('File %s is not an image file' % file2) out_file = util.automatic_output_file_name(out_file, file1, "stacked") w1, h1 = ImageFile(file1).get_dimensions() w2, h2 = ImageFile(file2).get_dimensions() tmpfile1 = file1 tmpfile2 = file2 util.logger.debug("Images dimensions: %d x %d and %d x %d", w1, h1, w2, h2) if direction == 'horizontal': filter_name = 'hstack' if h1 > h2: new_w2 = w2 * h1 // h2 tmpfile2 = rescale(file2, new_w2, h1) elif h2 > h1: new_w1 = w1 * h2 // h1 tmpfile1 = rescale(file1, new_w1, h2) else: filter_name = 'vstack' if w1 > w2: new_h2 = h2 * w1 // w2 tmpfile2 = rescale(file2, w1, new_h2) elif w2 > w1: new_h1 = h1 * w2 // w1 tmpfile1 = rescale(file1, w2, new_h1) # ffmpeg -i a.jpg -i b.jpg -filter_complex hstack output util.run_ffmpeg('-i "%s" -i "%s" -filter_complex %s "%s"' % (tmpfile1, tmpfile2, filter_name, out_file)) if tmpfile1 is not file1: util.delete_files(tmpfile1) if tmpfile2 is not file2: util.delete_files(tmpfile2) return out_file