фильтр drawtext

фильтр drawtext

Я хотел бы использовать фильтр Drawtext для визуализации строки с полупрозрачным белым текстом и черной рамкой.

Однако, похоже, есть известное ограничение в том, как фильтр рисует символы, которое приводит к тому, что альфа-канал шрифта не соблюдается, когда также включена граница. Это регистрируется здесьhttps://trac.ffmpeg.org/ticket/3571

Мой вопрос заключается в том, есть ли способ обойти это как-то, возможно, используя filter_complex для рисования текста без рамки, а затем используя фильтр наложения, чтобы каким-то образом снова нарисовать текст с рамкой и наложить его на исходный текст, чтобы просто взять рамку, тем самым получив тот же непрозрачный белый текст с черной рамкой.

Текущая команда:

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

Полный вывод:

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

Вывод показывает, что цвет текста изменяется под воздействием границы, хотя цвет шрифта в обоих экземплярах фильтра DrawText одинаков.

решение drawtext (это было заменено третьей командой @llogan в ответе ниже)

На основе второго решения @llogan drawtext эта версия добавляет возможность управлять непрозрачностью заливки с помощью стандартной альфы в fontcolor. Использование решения @llogan для управления непрозрачностью границы с помощью различных значений серого и исправление неровной визуализации текста:

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

решение1

фильтр drawtext

введите описание изображения здесь

Обходной путь может включать в себяальфамержиналожениефильтры:

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

Измените bordercolor, чтобы контролировать непрозрачность границы. В моих примерах использовались произвольные значения, поэтому вам нужно будет настроить их в соответствии с вашими потребностями. Используйте только серые цвета. Более темный оттенок даст менее прозрачный результат. Если вам не нравятся шестнадцатеричные значения, см. список допустимыхназвания цветов.

Thescale2refфильтр (срасколоть) можно использовать, если вы не хотите вручную подгонять фильтр источника цвета sк основному размеру входного изображения.

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

фильтр субтитров

Другим решением является использованиесубтитрыотфильтруйте с субтитрами Advanced SubStation Alpha (ASS), если вам нужны хард-сабы:

ffmpeg -f lavfi -i smptebars=s=320x180,format=rgb24 -vf subtitles=subs.ass -frames:v 1 hardsubs.png

Или мультиплексируйте файл ASS, если вам нужны софтсабы:

ffmpeg -i input -i subs.ass -map 0 -map 1 -c copy output.mkv

Пример 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

Связанный контент