
Me gustaría usar el filtro de texto de dibujo para representar una cadena con texto blanco semitransparente y un borde negro.
Sin embargo, parece haber una limitación conocida en la forma en que el filtro dibuja caracteres que hace que no se respete el color de fuente alfa cuando también se habilita un borde. Esto está registrado aquí.https://trac.ffmpeg.org/ticket/3571
Mi pregunta es si hay una manera de solucionar esto de alguna manera, tal vez usando filter_complex para dibujar el texto sin un borde y luego usar el filtro de superposición para dibujar de alguna manera el texto nuevamente con un borde y compilarlo sobre el texto inicial para simplemente tomar el borde, logrando así el mismo texto blanco opaco con un borde negro.
Comando actual:
ffmpeg \
-f lavfi \
-i "color=red:size=1920x1080" \
-vf "
drawtext=fontfile=/Library/Fonts/Arial.ttf:text=BORDER_OFF:[email protected]:fontsize=250:x=20:y=20,
drawtext=fontfile=/Library/Fonts/Arial.ttf:text=BORDER_ON:[email protected]:fontsize=250:x=20:y=20+(text_h+10):borderw=3:[email protected]" \
-frames:v 1 \
output.png
Salida completa:
ffmpeg -f lavfi -i "color=red:size=1920x1080" -vf "drawtext=fontfile=/Library/Fonts/Arial.ttf:[email protected]:fontsize=250:x=20:y=20:text=BORDER_OFF,drawtext=fontfile=/Library/Fonts/Arial.ttf:[email protected]:borderw=3:[email protected]:fontsize=250:x=20:y=20+(text_h+10):text=BORDER_ON" -frames:v 1 output.png
ffmpeg version N-94664-g0821bc4eee-tessus https://evermeet.cx/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with Apple LLVM version 10.0.1 (clang-1001.0.46.4)
configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay
libavutil 56. 33.100 / 56. 33.100
libavcodec 58. 55.101 / 58. 55.101
libavformat 58. 31.104 / 58. 31.104
libavdevice 58. 9.100 / 58. 9.100
libavfilter 7. 58.101 / 7. 58.101
libswscale 5. 6.100 / 5. 6.100
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
Input #0, lavfi, from 'color=red:size=1920x1080':
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> png (native))
Press [q] to stop, [?] for help
Output #0, image2, to 'output.png':
Metadata:
encoder : Lavf58.31.104
Stream #0:0: Video: png, rgb24, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
encoder : Lavc58.55.101 png
frame= 1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=0.283x
video:85kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
El resultado muestra que el borde está alterando el color del texto a pesar de que el color de fuente es el mismo en ambas instancias del filtro de texto de dibujo.
solución de dibujo de texto (esto ha sido reemplazado por un tercer comando @llogan en la respuesta a continuación)
Basada en la segunda solución de dibujo de texto de @llogan, esta versión agrega la capacidad de controlar la opacidad del relleno usando alfa estándar en el color de fuente. Usando la solución @llogan para controlar la opacidad del borde mediante diferentes valores de gris y corrige la representación irregular en el texto:
ffmpeg \
-y \
-f lavfi \
-i color=s=1920x1080:c=white \
-f lavfi \
-i color=s=1920x1080:c=black \
-f lavfi \
-i smptebars=s=1920x1080 \
-filter_complex "\
[0]drawtext=fontfile=/Library/Fonts/Arial.ttf:text='BORDER':fontcolor=white:fontsize=200:x=(w-text_w)/2:y=(h-text_h)/2:borderw=3:bordercolor=#bfbfbf[ahpla];
[1]drawtext=fontfile=/Library/Fonts/Arial.ttf:text='BORDER':fontcolor=black:fontsize=200:x=(w-text_w)/2:y=(h-text_h)/2[txt];
[2]drawtext=fontfile=/Library/Fonts/Arial.ttf:text='BORDER':[email protected]:fontsize=200:x=(w-text_w)/2:y=(h-text_h)/2[bg];
[ahpla]negate[alpha];
[txt][alpha]alphamerge[fg];
[bg][fg]overlay" \
-frames:v 1 \
output.png
Respuesta1
filtro de texto de dibujo
Una solución alternativa puede incluir lafusión alfaycubrirfiltros:
ffmpeg -y \
-f lavfi -i color=s=1920x1080 \
-f lavfi -i smptebars=s=1920x1080 \
-filter_complex \
"[0]drawtext=fontfile=/Library/Fonts/Arial.ttf:text='BORDER':fontcolor=black:fontsize=200:x=(w-text_w)/2:y=(h-text_h)/2:borderw=3:bordercolor=#404040[border];
[0][border]alphamerge[alpha];
[1][alpha]overlay=format=rgb,drawtext=fontfile=/Library/Fonts/Arial.ttf:text='BORDER':[email protected]:fontsize=200:x=(w-text_w)/2:y=(h-text_h)/2" \
-frames:v 1 \
output.png
Cambie bordercolor
para controlar la opacidad del borde. Mis ejemplos utilizaron valores arbitrarios, por lo que deberás ajustarlos según tus necesidades. Utilice únicamente colores grises. Un tono más oscuro producirá un resultado menos transparente. Si no te gustan los valores hexadecimales, consulta la lista de valores válidos.nombres de colores.
Elescala2reffiltro (condividir) se puede utilizar si no desea hacer coincidir manualmente el filtro de fuente de color s
con el tamaño de entrada principal.
ffmpeg -y \
-f lavfi -i color \
-f lavfi -i smptebars=s=1920x1080 \
-filter_complex \
"[0][1]scale2ref[color][mainbg];
[color]split[colorbg0][colorbg1];
[colorbg0]drawtext=fontfile=/Library/Fonts/Arial.ttf:text='BORDER':fontcolor=black:fontsize=200:x=(w-text_w)/2:y=(h-text_h)/2:borderw=3:bordercolor=#404040[border];
[colorbg1][border]alphamerge[alpha];
[mainbg][alpha]overlay=format=rgb,drawtext=fontfile=/Library/Fonts/Arial.ttf:text='BORDER':[email protected]:fontsize=200:x=(w-text_w)/2:y=(h-text_h)/2" \
-frames:v 1 \
output.png
filtro de subtítulos
Otra solución es utilizar elsubtítulosfiltra con subtítulos Advanced SubStation Alpha (ASS) si quieres subtítulos duros:
ffmpeg -f lavfi -i smptebars=s=320x180,format=rgb24 -vf subtitles=subs.ass -frames:v 1 hardsubs.png
O mux el archivo ASS si quieres softsubs:
ffmpeg -i input -i subs.ass -map 0 -map 1 -c copy output.mkv
Ejemplo de archivo ASS:
[Script Info]
; Script generated by Aegisub 3.2.2
; http://www.aegisub.org/
Title: Default Aegisub file
ScriptType: v4.00+
WrapStyle: 0
ScaledBorderAndShadow: yes
YCbCr Matrix: None
[Aegisub Project Garbage]
Last Style Storage: Default
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Bitstream Vera Sans,92,&HB4FFFFFF,&H000000FF,&H4B000000,&H00000000,0,0,0,0,100,100,0,0,1,4,0,5,10,10,10,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,,BORDER ON