Working on Python code to read the contents of periodically changed file (information on an MP3) and create a specific animated gif based on the information at hand, using Wand. I have however been having a significant problem with the gif refusing to save after a few passes; after two or three passes, either the image.save() runs infinitely or the processing time increases dramatically. I see no reason for the sudden change.
The code here is a test case built to verify that the problem was not with the file reading, which it is not.
# coding=latin-1
from wand.image import Image # ImageMagick
from wand.font import Font # IM Font Handler
from wand.drawing import Drawing # IM Drawing API
from wand.color import Color # IM Colour definitions
from watchdog.observers import Observer # Event monitors
from watchdog.events import FileSystemEventHandler # Event handlers
import time # for the stopwatch
import sys, os
FONT_NAME = 'c://windows//fonts//alarm clock.ttf';
FONT_SIZE = 80;
SPACING = 1;
def ImageMaker(title, album, composer, playtime):
print("DEBUG: Entering ImageMaker()");
start = time.time();
title = title.ljust(60,' '); # these strings are space-padded to work properly in draw.text()
album = album.ljust(60,' ');
composer = composer.ljust(60,' ');
details = [title, album, composer];
counter = 0;
frame_counter = 0;
bg = Image(filename="nowplaying_background.png"); # this is a static, pre-generated file
gif = Image(background=Color('rgb(0,0,0)'), height=200, width=1440);
if (int(playtime) > 45): # the script takes so long, very short MP3s finish before the script does
for x in details:
while (counter <= len(x)+1 and counter < 30 and len(x) != 0):
with Image(height=200, width=1440, depth=8) as img:
with Drawing() as draw:
draw.font = FONT_NAME;
draw.font_size = FONT_SIZE;
draw.text_interline_spacing = SPACING;
draw.fill_color = Color('rgb(255, 194, 0)');
draw.stroke_width = 0;
a = x[(29-counter):30]; # start at 30, step back to 0
b = x[59-counter:len(x)]; # start at 60, step back to 30
draw.text(20, 65, a); # top line text
draw.text(20, 130, b); # bottom line text
draw(img);
with Image(height=200, width=1440) as final:
final.composite(bg); # draw static bg on the image context
final.composite(img); # draw the current fg over the bg
if(frame_counter > 0):
gif.sequence.append(final);
else:
gif.sequence[0] = final;
final.clear();
gif.sequence[frame_counter].delay = 30;
img.clear();
counter += 1;
frame_counter += 1;
counter = 0;
print("DEBUG: Exiting frame generator");
gif.sequence[29].delay = 200; # these set the delays between the three elements longer
gif.sequence[59].delay = 200; # so they're more readable
gif.sequence[89].delay = 200;
gif.type = 'optimize';
gif.save(filename="c://users/magni/desktop/nowplaying.gif");
gif.destroy();
bg.destroy();
else:
print("DEBUG: Skipping image generation, song is too short");
end = time.time();
elapsed = end - start;
print("Time to completition: ", elapsed);
# These are simulated samples
ImageMaker("ABCDEF", "GHIJKLMNO", "QRSTUVWXYZ", "60");
ImageMaker("ABCDEF", "GHIJKLMNO", "QRSTUVWXYZ", "60");
ImageMaker("QRSTUVWXYZ", "ABCDEF", "GHIJKLMNO", "90");
ImageMaker("QRSTUVWXYZ", "ABCDEF", "GHIJKLMNO", "90");
ImageMaker("American Meeting", "Teitoku no Ketsudan 2", "Yoichiro Yoshikawa", "133");
ImageMaker("American Meeting", "Teitoku no Ketsudan 2", "Yoichiro Yoshikawa", "133");
Example output:
DEBUG: Entering ImageMaker()
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
Time to completition: 22.29582381248474
DEBUG: Entering ImageMaker()
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
Time to completition: 23.027299642562866
DEBUG: Entering ImageMaker()
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
Time to completition: 21.273354291915894
DEBUG: Entering ImageMaker() on a modified file
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
Time to completition: 139.14677023887634
DEBUG: Entering ImageMaker()
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
DEBUG: Exiting frame generator
After fifteen minutes, the fifth cycle hadn't finished and was manually terminated. The destination file (nowplaying.gif) continued to grow during that time, and was nearly 2 megabytes in size when the process was killed. The final gif is broken, which makes sense as it wasn't completely saved.
I'm unsure if I've done something wrong or I've stumbled on a bug in the Wand implementation (version 0.6.1, the latest available). My Python skills are not extremely good, but I have perused bug reports and documentation, and I see nothing on this particular issue.