Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new TextClip with original text shape #2285

Closed
GrayFL opened this issue Dec 7, 2024 · 5 comments
Closed

Add new TextClip with original text shape #2285

GrayFL opened this issue Dec 7, 2024 · 5 comments
Labels
feature-request Request for a new feature or additional functionality. v2.x Issues based on MoviePy version 2.0 and upwards

Comments

@GrayFL
Copy link

GrayFL commented Dec 7, 2024

While using version 2.x of moviepy, I noticed that the position of TextClip has changed in all videos generated using past code;

Analyzing it, I found that TextClip now uses PIL's multiline_textbbox to look for borders and weed out the excess. But then 'LINE' and 'xxxx' will not have the same shape (I mean '■■■■'), and I can't control two different pieces of text with different content to be in the same position just by using with_position

So I'd like to be able to provide the raw image output by PIL without any complicated margin and text_size calculations, like the following:

class SimpleTextClip(ImageClip):
    @convert_path_to_string("filename")
    def __init__(
        self,
        font,
        text=None,
        filename=None,
        font_size=None,
        # size=(None, None),
        # margin=(None, None),
        color="black",
        bg_color=None,
        stroke_color=None,
        stroke_width=0,
        method="label",
        text_align="left",
        # horizontal_align="center",
        # vertical_align="center",
        interline=4,
        transparent=True,
        duration=None,
    ):

        try:
            _ = ImageFont.truetype(font)
        except Exception as e:
            raise ValueError(
                "Invalid font {}, pillow failed to use it with error {}".format(font, e)
            )

        if filename:
            with open(filename, "r") as file:
                text = file.read().rstrip()  # Remove newline at end

        if text is None:
            raise ValueError("No text nor filename provided")

        # Trace the image
        img_mode = "RGBA" if transparent else "RGB"

        if bg_color is None and transparent:
            bg_color = (0, 0, 0, 0)

        pil_font = ImageFont.truetype(font, font_size)

        left, top, right, bottom = ImageDraw.Draw(Image.new("RGB", (1, 1))).multiline_textbbox(
            (0,0),text=text,
            font=pil_font,
            spacing=interline,
            align=text_align,
            stroke_width=stroke_width,
            anchor="la",
            )
        img_width, img_height = int(np.ceil(right)), int((np.ceil(bottom)))
        # get the original shape of text
        img = Image.new(img_mode, (img_width, img_height), color=bg_color)
        draw = ImageDraw.Draw(img)

        draw.multiline_text(
            xy=(0, 0),
            text=text,
            fill=color,
            font=pil_font,
            spacing=interline,
            align=text_align,
            stroke_width=stroke_width,
            stroke_fill=stroke_color,
            anchor="la",
        )

        img_numpy = np.array(img)

        ImageClip.__init__(
            self, img=img_numpy, transparent=transparent, duration=duration
        )
        self.text = text
        self.color = color
        self.stroke_color = stroke_color
@GrayFL GrayFL added the feature-request Request for a new feature or additional functionality. label Dec 7, 2024
@keikoro keikoro added the v2.x Issues based on MoviePy version 2.0 and upwards label Dec 8, 2024
@RaSan147
Copy link

Also I am getting the text cut when generating by TextClip
image
Same code with v1.X
image

@harsh-zymr
Copy link

harsh-zymr commented Jan 6, 2025

Facing the same issue. There are only 2 choices, either get the text cut like shown by @RaSan147 or have them up/down scattered.

Screenshot 2025-01-06 at 6 22 19 PM

Not sure how to align them well. In an earlier version, it was aligned properly. Maybe @GrayFL 's solution is the key. It does work.

@OsaAjani
Copy link
Collaborator

Hi, I absolutely hate the way textclip currently work, in my own defense text with Pillow is a pain second only to hitting your pinky in the table foot. I will try to improve things in near future, I hope I can achieve a more coherent behaviour and fix the current text cutting problem.

@OsaAjani OsaAjani reopened this Jan 10, 2025
@OsaAjani
Copy link
Collaborator

Hi, making progress on that one, still some tests to run, but I think I should be able to provide a fix for the current text cutting/alignment problem in the next days.

@OsaAjani
Copy link
Collaborator

This issue is closely related to #2268. We're merging the discussion into that issue to keep everything organized. Please follow the updates there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for a new feature or additional functionality. v2.x Issues based on MoviePy version 2.0 and upwards
Projects
None yet
Development

No branches or pull requests

5 participants