Эффект масштабирования текста Дрожание

Я создал анимацию масштабирования текста с помощью MoviePy и Gizeh. Однако результаты оказались разными, когда код запускался на разных ОС. Следующие два GIF генерируются одним и тем же кодом Python. Эффект выглядит довольно хорошо на MacOS, но плохо на Linux.

довольно хорошо на MacOS

довольно хорошо для MacOS

эффект дрожания в Linux

эффект дрожания в Linux

Я уверен, что версии библиотек (MoviePy, Gizeh, Cairocffi, cffi и т. д.) одинаковы в обеих системах. Я также пытался увеличить частоту кадров или уменьшить размер теста, но это не сработало.

Я не знаю, может ли это быть проблемой или плохим кодированием с моей стороны.

Я попытался выяснить, что вызвало эту проблему. Я нашел возвращаемые значения функции ctx.text_extents(txt) в gizeh.py, строка 489 (аналогично cairo_text_extents, в библиотеке cairocffi, context.py, строка 2003) меняется каждый кадр в Linux. А на Mac функция всегда возвращает одни и те же значения. Однако, даже если я зафиксировал значения, эффект остался прежним.

import sys
import gizeh as gz
from moviepy.editor import *

def make_frame(t):
    surface = gz.Surface(360, 180, bg_color=(0, 0, 0))
    text = gz.text('ENLARGE', fontsize=40, fontfamily='Arial Unicode',
                   fill=(255,255,255), xy=(180, 90), fontweight='normal')
    text = text.scale(1+0.5*t, center=[180, 90])
    text.draw(surface)
    return surface.get_npimage()

child_clip = VideoClip(make_frame, duration=3)
child_clip.write_gif('Result.gif',fps=24)

Я нашел эту проблему в Каирской библиотеке. Я написал простую демонстрацию для создания последовательности изображений, увеличивающих текстовую строку. И я напечатал возвращаемые значения функции cairo_text_extents(), которые указывали границы строки. Я запускаю один и тот же код в Linux и MacOS. Значения остались прежними в MacOS. В то время как в Linux значения менялись в каждом кадре. Пытаюсь понять, почему.

#include "cairo.h"
#include <stdio.h>


int draw (const char* filename, float t)
{
    cairo_surface_t *ImageSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,360,360);

    cairo_t *cr = cairo_create(ImageSurface);

    cairo_set_source_rgb (cr, 1., 1., 1.);
    cairo_paint (cr);

    cairo_matrix_t matrix;
    float scale = (1+0.5*t);
    float offset = -(0.5*t)/2*355;
    matrix.xx = scale;
    matrix.xy = 0;
    matrix.x0 = offset;
    matrix.yx = 0;
    matrix.yy = scale;
    matrix.y0 = offset;

    cairo_set_matrix(cr,&matrix);

    cairo_font_options_t *font_options = cairo_font_options_create();
    cairo_font_options_set_antialias(font_options,CAIRO_ANTIALIAS_NONE);
    cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE);
    cairo_font_options_set_hint_metrics(font_options,CAIRO_HINT_METRICS_OFF);
    cairo_set_font_options(cr,font_options);

    cairo_select_font_face (cr, "Arial Unicode",
                CAIRO_FONT_SLANT_NORMAL,
                CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size(cr,60);

    cairo_text_extents_t *text_extents = new cairo_text_extents_t;
    cairo_text_extents(cr,"ENLARGE",text_extents);
    printf("%f %f %f %f %f %f\n",text_extents->width,
                                text_extents->height,
                                text_extents->x_advance,
                                text_extents->y_advance,
                                text_extents->x_bearing,
                                text_extents->y_bearing);
    int x_shift = -text_extents->width/2-text_extents->x_bearing;
    int y_shift = -text_extents->height/2-text_extents->y_bearing;
    int x = 180 + x_shift;
    int y = 180 + y_shift;
    cairo_move_to (cr, x, y);
    cairo_text_path(cr,"ENLARGE");
    cairo_set_source_rgb(cr,0,0,0);
    cairo_fill(cr);

    cairo_surface_write_to_png(ImageSurface,filename);

    cairo_font_options_destroy(font_options);
    delete text_extents;
    cairo_destroy(cr);
    cairo_surface_destroy(ImageSurface);


    return 0;
}

int main()
{
    int i = 0;
    for(i = 0;i<10;i++)
    {
        char filename[256] = "";
        sprintf(filename,"result_%d.png",i);
        float t = 1.0/10 * i;

        draw((const char*)filename,t);
    }
    printf("hello world!!!\n");

    getchar();

    return 0;
}

person 陈羽飞    schedule 24.04.2018    source источник


Ответы (1)


Вы должны отключить подсказку шрифта в Cairo (или fontconfig). Я предполагаю, что это означает установить CAIRO_HINT_METRICS_OFF и/или CAIRO_HINT_STYLE_NONE. Впрочем, я даже не знаю, что такое Гизе и поэтому не могу вам подсказать, как отключить там хинтинг.

person Uli Schlachter    schedule 26.04.2018
comment
Gizeh — это библиотека Python для векторной графики, основанная на cairo.ссылка Теперь я нашел эту проблему в библиотеке Cairo. . Я обнаружил, что если установить cairo_matrix_t для cairo_t, функция cairo_text_extents() будет возвращать разные значения cairo_text_extents_t в Linux. Но в MacOS возвращаемое значение cairo_text_extents осталось прежним. Я отключил подсказку шрифта, но это не сработало. Также пытался отключить сглаживание шрифтов и метрики подсказок. Я не уверен, что это может быть проблема, вызванная ОС, файлом шрифта (ttf) или параметрами шрифта. - person 陈羽飞; 27.04.2018