python - 文本缩放效果颤抖

标签 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 第 489 行中的函数 ctx.text_extents(txt)(与 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;
}

最佳答案

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

关于python - 文本缩放效果颤抖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49995318/

相关文章:

python - 将列表的列表转换为 Numpy 数组而不携带列表

python - 我无法打印变量的最终值

python - 在Python中返回整个字符串;删除 无

animation - 从右到左方向动画 UIView,iPhone

ios - 将蒙版的大小更改为带有动画的方向

c - 了解 cairo_scale()

python - 如何在 python 中使用 opencv 按下按键时准确地从相机流中捕获帧?

c - 绘制回调内绘制和绘制回调外绘制

c# - Cairo 可以直接绘制到 Gtk.Pixbuf 上吗?

android - 根据位置为 RecyclerView 项目设置动画