[FFmpeg-devel] [PATCH] lavfi/drawtext: add option for drawing border around text
Ramiro Polla
ramiro.polla at gmail.com
Fri Jan 10 07:37:36 CET 2014
On Thu, Jan 9, 2014 at 12:42 PM, Ramiro Polla <ramiro.polla at gmail.com> wrote:
> On Thu, Jan 9, 2014 at 8:26 AM, Stefano Sabatini <stefasab at gmail.com> wrote:
>> On date Thursday 2014-01-09 00:13:37 -0200, Ramiro Polla encoded:
>>> From 52b6cda0ee5bfaf6e594eb5a7923be00eac575d8 Mon Sep 17 00:00:00 2001
>>> From: Ramiro Polla <ramiro.polla at gmail.com>
>>> Date: Thu, 9 Jan 2014 00:05:43 -0200
>>> Subject: [PATCH] lavfi/drawtext: add option for drawing border around text
>>>
>>> ---
>>> doc/filters.texi | 11 +++++++++++
>>> libavfilter/vf_drawtext.c | 15 +++++++++++++++
>>> 2 files changed, 26 insertions(+)
>>
>> This feature was implemented in the original VHOOK drawtext filter
>> (was named "outline"). Since the rendering result was pretty poor I
>> decided to drop it.
>>
>>> diff --git a/doc/filters.texi b/doc/filters.texi
>>> index c896edb..9f97dc0 100644
>>> --- a/doc/filters.texi
>>> +++ b/doc/filters.texi
>>> @@ -3548,6 +3548,17 @@ option, check the "Color" section in the ffmpeg-utils manual.
>>>
>>> The default value of @var{boxcolor} is "white".
>>>
>>> + at item border
>>> +Used to draw a 1-pixel-thick border around text using @var{bordercolor}.
>>> +Value should be either 1 (enable) or 0 (disable).
>>> +The default value of @var{border} is 0.
>>> +
>>> + at item bordercolor
>>> +The color to be used for drawing border around text. For the syntax of this
>>> +option, check the "Color" section in the ffmpeg-utils manual.
>>> +
>>> +The default value of @var{bordercolor} is "black".
>>> +
>>> @item expansion
>>> Select how the @var{text} is expanded. Can be either @code{none},
>>> @code{strftime} (deprecated) or
>>> diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
>>> index 91b8218..c14bac3 100644
>>> --- a/libavfilter/vf_drawtext.c
>>> +++ b/libavfilter/vf_drawtext.c
>>> @@ -136,6 +136,7 @@ typedef struct {
>>> int shadowx, shadowy;
>>> unsigned int fontsize; ///< font size to use
>>>
>>> + short int draw_border; ///< draw border around text - true or false
>>> short int draw_box; ///< draw box around text - true or false
>>> int use_kerning; ///< font kerning is used - true/false
>>> int tabsize; ///< tab size
>>> @@ -144,6 +145,7 @@ typedef struct {
>>> FFDrawContext dc;
>>> FFDrawColor fontcolor; ///< foreground color
>>> FFDrawColor shadowcolor; ///< shadow color
>>> + FFDrawColor bordercolor; ///< border color
>>> FFDrawColor boxcolor; ///< background color
>>>
>>> FT_Library library; ///< freetype font library handle
>>> @@ -179,6 +181,8 @@ static const AVOption drawtext_options[]= {
>>> {"fontcolor", "set foreground color", OFFSET(fontcolor.rgba), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
>>> {"boxcolor", "set box color", OFFSET(boxcolor.rgba), AV_OPT_TYPE_COLOR, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS},
>>> {"shadowcolor", "set shadow color", OFFSET(shadowcolor.rgba), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
>>> + {"bordercolor", "set border color", OFFSET(bordercolor.rgba), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
>>> + {"border", "set border", OFFSET(draw_border), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 , FLAGS},
>>> {"box", "set box", OFFSET(draw_box), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 , FLAGS},
>>> {"fontsize", "set font size", OFFSET(fontsize), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX , FLAGS},
>>> {"x", "set x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX, FLAGS},
>>> @@ -559,6 +563,7 @@ static int config_input(AVFilterLink *inlink)
>>> ff_draw_init(&s->dc, inlink->format, 0);
>>> ff_draw_color(&s->dc, &s->fontcolor, s->fontcolor.rgba);
>>> ff_draw_color(&s->dc, &s->shadowcolor, s->shadowcolor.rgba);
>>> + ff_draw_color(&s->dc, &s->bordercolor, s->bordercolor.rgba);
>>> ff_draw_color(&s->dc, &s->boxcolor, s->boxcolor.rgba);
>>>
>>> s->var_values[VAR_w] = s->var_values[VAR_W] = s->var_values[VAR_MAIN_W] = inlink->w;
>>> @@ -995,6 +1000,16 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame,
>>> frame->data, frame->linesize, width, height,
>>> s->x, s->y, box_w, box_h);
>>>
>>
>>> + if (s->draw_border) {
>>> + int offsets[4][2] = { { -1, -1 }, { -1, +1 }, { +1, -1 }, { +1, +1 } };
>>> + for (i = 0; i < 4; i++) {
>>> + ret = draw_glyphs(s, frame, width, height, s->bordercolor.rgba,
>>> + &s->bordercolor, offsets[i][0], offsets[i][1]);
>>> + if (ret < 0)
>>> + return ret;
>>> + }
>>> + }
>>
>> This will require printing the glyphs four times, which is not very
>> efficient. Alternatively you could implement a system like the one in
>> the VHOOK filter, which would be faster but more complicate
>> implementation-wise.
>
> Indeed, it is more complicated implementation-wise. There is also the
> option of using the FreeType stroker, but that library has a horrible
> API and the examples are confusing, so I couldn't get it to work.
Got it! New patches sent.
More information about the ffmpeg-devel
mailing list