question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TextClip produces low quality text

See original GitHub issue

I think that the usage of ImageMagick to render texts is a bad option, but maybe I’m wrong and someone could explain me how to achieve good quality texts using TextClip. To illustrate this, I’ve done a comparison between gizeh vs PIL vs TextClip:

import math

import gizeh as gz  # pip install gizeh
import numpy as np
from moviepy import *
from PIL import Image, ImageFont, ImageDraw


SIZE = (300, 200)
BG_COLOR = (255, 90, 0)
DURATION = 2
FPS = 1

TEXT = "Text"
TEXT_SIZE = (200, 100)
TEXT_POSITION = (0, 0)
TEXT_ROTATION = 45
FONT_SIZE = 50
TEXT_COLOR_RGB = (74, 74, 74)
TEXT_COLOR_HEX = "#4a4a4a"
FONT = "Amiri-Bold"


def create_gizeh_demo():
    def create_gizeh_surface():
        surface = gz.Surface(
            width=SIZE[0],
            height=SIZE[1],
            bg_color=(BG_COLOR[0] / 255, BG_COLOR[1] / 255, BG_COLOR[2] / 255),
        )
        text = gz.text(
            TEXT,
            xy=(
                TEXT_SIZE[0] / 2 + TEXT_POSITION[0],
                TEXT_SIZE[1] / 2 + TEXT_POSITION[1],
            ),
            fill=(
                TEXT_COLOR_RGB[0] / 255,
                TEXT_COLOR_RGB[1] / 255,
                TEXT_COLOR_RGB[2] / 255,
            ),
            fontfamily=FONT.split("-")[0],  # only family
            fontsize=FONT_SIZE,
        )
        text = text.rotate(
            -math.radians(TEXT_ROTATION),  # Gizeh accepts radians and inversed
            center=(
                (TEXT_POSITION[0] + SIZE[0]) / 2,
                (TEXT_POSITION[1] + SIZE[1]) / 2,
            ),
        )
        text.draw(surface)
        return surface.get_npimage()

    surface = create_gizeh_surface()

    text_clip = VideoClip(lambda t: surface, duration=DURATION).with_fps(FPS)
    text_clip.size = SIZE
    return CompositeVideoClip([text_clip], size=SIZE).with_duration(DURATION)


def create_PIL_demo():
    img = Image.new("RGB", size=SIZE, color=BG_COLOR)
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype(f"~/.local/share/fonts/{FONT}.ttf", size=FONT_SIZE)
    draw.text((50, 50), TEXT, font=font, fill=TEXT_COLOR_RGB)
    img = img.rotate(
        TEXT_ROTATION,
        expand=False,
        fillcolor=BG_COLOR,
    )

    img = np.array(img)

    return VideoClip(lambda t: img, duration=DURATION).with_fps(FPS)


def create_TextClip_demo():
    bg_clip = ColorClip(size=SIZE, color=BG_COLOR, duration=DURATION).with_position(
        TEXT_POSITION
    )
    text_clip = (
        TextClip(
            TEXT,
            color=TEXT_COLOR_HEX,
            size=TEXT_SIZE,
            font=FONT,
            font_size=FONT_SIZE,
            stroke_color=TEXT_COLOR_HEX,
        )
        .with_position(TEXT_POSITION)
        .with_duration(DURATION)
    )
    text_clip = text_clip.rotate(TEXT_ROTATION, unit="deg", expand=True)
    return CompositeVideoClip([bg_clip, text_clip]).with_duration(DURATION)


final = concatenate_videoclips(
    [create_gizeh_demo(), create_PIL_demo(), create_TextClip_demo()]
)
final.preview()

Rendered result (MP4)

cairo_pil_imagemagick

The result is that Gizeh creates a text with good quality using Cairo (first scene), followed by PIL (second scene) and moviepy using ImageMagick creates a low quality text (third scene).

Specifications

  • Python Version: 3.8.5
  • Moviepy Version: master
  • Platform Name: Ubuntu
  • Platform Version: 20.04
  • ImageMagick Version: 6.9.10-23
  • PIL version: 8.1.0
  • cairocffi version: 1.2.0
  • gizeh version: 0.1.11

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
Zulkocommented, Jan 21, 2021

If you manage that I would vote for it (@tburrows13 what do you think?). Note that this would require some work to update the scripts that use the current ImageMagick-based text API, but that’s allowed by the major version bump in v2.0.

1reaction
tburrows13commented, Jan 20, 2021

I’m seeing now your implementation of TextClip using PIL @tburrows13. What do you think that is worth to make?

  • Implementation for PIL.
  • Implementation for Cairo.
  • Remove support for ImageMagick or not?
  • Support all 3 providers and create a provider argument to select between them?

Yep, as I noted, I’d like to completely remove ImageMagick (it is only used here and as one of 3 optional gif renderers - I don’t think it will be missed). This allows us to remove a lot of the complexity of installation.

Between PIL and Cairo/Gizeh, if PIL can get equivalent results, then it is preferable. If Gizeh is as easy to install as PIL is, then that would be fine as well.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TextClip — MoviePy 2.0.0.dev2 documentation
Class for autogenerated text clips. Creates an ImageClip originating from a script-generated text image. Requires ImageMagick. Parameters. text. A string of the ...
Read more >
Classes of Video Clips — MoviePy 1.0.2 documentation
This method is intensively used to produce new clips every time there is an outplace transformation of the clip (clip.resize, clip.subclip, etc.).
Read more >
background-clip - CSS: Cascading Style Sheets | MDN
The background-clip CSS property sets whether an element's background extends underneath its border box, padding box, or content box.
Read more >
How to Fix Jagged Poor Quality Fonts or Text on Windows
If your fonts are low quality or jagged in your browser or applications then make sure font smoothing is enabled on Windows.
Read more >
Great CSS Text Animation Examples You Can Use
This latest CSS script-based animation makes the font looks clean and ... This only takes a small space and allows users to resize...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found