文字缩放效果颤抖

时间:2018-04-24 07:03:10

标签: python animation cairo moviepy cffi

我使用MoviePy和Gizeh创建了一个文本缩放动画。但是,当代码在不同的操作系统上运行时,结果会有所不同。以下两个gif由相同的python代码生成。这种效果在MacOS上看起来相当不错,但在Linux上却很差。

非常适合MacOS

pretty good on MacOS

在Linux上影响颤抖

effect trembling on Linux

我确定两个系统上的库(MoviePy,Gizeh,Cairocffi,cffi等)版本都是相同的。我也试过高fps或缩小测试但它没有用。

我不知道这可能是我身边的问题还是编码错误。

我试图找出导致此问题的原因。我找到了返回值  gizeh.py中的函数 ctx.text_extents(txt)第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;
}

1 个答案:

答案 0 :(得分:2)

您必须在Cairo(或fontconfig)中禁用字体提示。我想这意味着设置CAIRO_HINT_METRICS_OFF和/或CAIRO_HINT_STYLE_NONE。但是,我甚至不知道Gizeh是什么,所以我不能告诉你如何在那里禁用暗示。

相关问题