Ref: https://github.com/emcconville/wand/issues/564
I think the following codes are messing with outline.
########## main func for image rendering ##############
def export_caption(caption, filename):
'''Creates a .png file <filename> suitable for bdsup2sub that displays
the given caption.'''
img = Image(width=XSIZE, height=YSIZE)
# by default wand will use the text's baseline as y-coord which is bad,
# because we'd never know where we end, so set the gravity to north_west
# Beware: it seems like if we set text_alignment='center' so we could
# use wand's multiline text feature the gravity setting will be lost
# irrevocably, so we need to deal with multiline captions ourselves
img.gravity = 'north_west'
box = Drawing()
# Color() handles 'none' by itself, case-independently
box.fill_color = Color(OPTS.BOXCOLOR)
draw = Drawing()
draw.fill_color = Color(OPTS.FILLCOLOR)
draw.font = FONT
draw.font_size = FONTSIZE
draw.text_encoding = ENCODING
if OPTS.ANTIALIASING:
draw.text_antialias = True
else:
draw.text_antialias = False
if OUTLINEWIDTH:
draw.stroke_color = "BLACK"
draw.stroke_width = OUTLINEWIDTH
if OPTS.ANTIALIASING:
draw.stroke_antialias = True
else:
draw.stroke_antialias = False
lines = [line.strip() for line in caption.splitlines() if line.strip()]
# padding for the text's bounding box
padx, pady = BOXPADDING
# calculate the max. allowed text width, and don't forget the outline but
# ignore the box; keep a few extra px. (1% of XSIZE) in reserve,
# just to be on the safe side in case we have rounding errors
max_textwidth = int(round(XSIZE * MAXLINESIZE / 100)) - \
2 * OUTLINEWIDTH - int(round(0.01 * XSIZE))
# now loop through the list of strings, calculate each string's width and
# if necessary split it in two;
# repeat this until no line needs to be wrapped
lines, wmax, line_widths = fix_caption(lines, max_textwidth, img, draw)
# collect info for which lines we need y box padding;
# this seems useful to avoid a too big offset between text lines,
# which may look odd, esp. when the box is transparent
i = 0
padinfo = []
for lw in line_widths:
a, b, c = 0, 0, 0 # top padding, bottom padding, Y incr. of next line
if i == 0:
# the first line needs top padding
a = pady
elif line_widths[i-1] < lw:
# previous line is smaller, so we need top padding
a = pady
if i == len(line_widths) - 1:
# the last line needs bottom padding
b = pady
elif line_widths[i+1] < lw:
# next line is smaller, so we need bottom padding
b = pady
elif line_widths[i+1] > lw:
# next line is bigger, shift the Y-increment by pady
c = pady
i += 1
padinfo.append((a, b, c))
# width of the box == max. textwidth + 2* (boxpad + outline width)
wmax = wmax + 2*padx + 2*OUTLINEWIDTH
# now all lines should be safe to fit on the screen,
# so start drawing
Y = 0
i = 0
bottom = 0
for line in lines:
s = line.strip()
m = draw.get_font_metrics(img, line)
w, h = int(m.text_width), int(m.text_height)
# make sure the smaller line appears centered relative to the
# bigger line
if wmax > XSIZE:
# may happen if an insane x box padding was given;
# make sure the text will be centered anyway, the excess box
# will be chopped off later
X = int((XSIZE - w) / 2)
else:
X = int((wmax - w) / 2)
a, b, c = padinfo[i]
# draw the bounding box
if OPTS.BOXCOLOR.lower() != 'none':
box.rectangle(X - OUTLINEWIDTH - padx,
Y - OUTLINEWIDTH - a,
X + w + OUTLINEWIDTH + padx,
Y + h + OUTLINEWIDTH + b)
box(img)
# draw the text and shift the Y position to the correct
# coordinate for the following line (if any)
draw.text(X, Y, s)
draw(img)
# store bottom Y coord
bottom = Y + h + OUTLINEWIDTH + b
Y = bottom + c + OUTLINEWIDTH + 2 # 1 px. extra so the boxes won't overlap
i += 1
x0, y0, x1, y1 = 0, 0, wmax + 1, bottom + 1
# cut the text box from the surrounding void
if y1 > YSIZE:
# may happen if the font is too big or an insane y boxpadding is set
printerror('\nError: generated subtitle image exceeds screen height')
printerror('The offending subtitle text was:')
for line in caption.splitlines():
printerror(' ' + line)
printerror('This subtitle will not look as expected.')
y1 = YSIZE
if x1 > XSIZE:
# may happen if the user set insane boxpadding values, making
# it impossible to wrap the text to fit into one line
printerror('\nError: generated subtitle image exceeds screen width')
printerror('The offending subtitle text was:')
for line in caption.splitlines():
printerror(' ' + line)
printerror('This subtitle may not look as expected.')
x1 = XSIZE
img.crop(x0, y0, x1, y1)
# write file and return the size for our xml content
img.format = 'png'
img.save(filename=filename)
box.destroy()
draw.destroy()
img.destroy()
return wmax+1, bottom+1
Whole file:
srt2vobsub.zip