Example #1
0
def test_margin(ClipClass, margin_size, margins, color, expected_result):
    if ClipClass is BitmapClip:
        clip = BitmapClip([["RRR", "RRR"], ["RRR", "RRR"]], fps=1)
    else:
        clip = ColorClip(color=(255, 0, 0), size=(3, 2),
                         duration=2).with_fps(1)

    # if None, set default argument values
    if color is None:
        color = (0, 0, 0)

    if margins is None:
        margins = [0, 0, 0, 0]
    left, right, top, bottom = margins

    new_clip = margin(
        clip,
        margin_size=margin_size,
        left=left,
        right=right,
        top=top,
        bottom=bottom,
        color=color,
    )

    assert new_clip == BitmapClip(expected_result, fps=1)
Example #2
0
def test_colorx():
    color_dict = {"H": (0, 0, 200), "L": (0, 0, 50), "B": (0, 0, 255), "O": (0, 0, 0)}
    clip = BitmapClip([["LLO", "BLO"]], color_dict=color_dict, fps=1)

    clipfx = colorx(clip, 4)
    target = BitmapClip([["HHO", "BHO"]], color_dict=color_dict, fps=1)
    assert target == clipfx
Example #3
0
def test_freeze_region():
    clip = BitmapClip([["AAB", "CCC"], ["BBR", "DDD"], ["CCC", "ABC"]], fps=1)

    # Test region
    clip1 = freeze_region(clip, t=1, region=(2, 0, 3, 1))
    target1 = BitmapClip([["AAR", "CCC"], ["BBR", "DDD"], ["CCR", "ABC"]], fps=1)
    assert clip1 == target1

    # Test outside_region
    clip2 = freeze_region(clip, t=1, outside_region=(2, 0, 3, 1))
    target2 = BitmapClip([["BBB", "DDD"], ["BBR", "DDD"], ["BBC", "DDD"]], fps=1)
    assert clip2 == target2
Example #4
0
def test_invert_colors():
    clip = BitmapClip(
        [["AB", "BC"]],
        color_dict={"A": (0, 0, 0), "B": (50, 100, 150), "C": (255, 255, 255)},
        fps=1,
    )

    clip1 = invert_colors(clip)
    target1 = BitmapClip(
        [["CD", "DA"]],
        color_dict={"A": (0, 0, 0), "D": (205, 155, 105), "C": (255, 255, 255)},
        fps=1,
    )
    assert clip1 == target1
Example #5
0
def test_time_mirror():
    clip = BitmapClip([["AA", "AA"], ["BB", "BB"], ["CC", "CC"]], fps=1)

    clip1 = time_mirror(clip)
    target1 = BitmapClip([["CC", "CC"], ["BB", "BB"], ["AA", "AA"]], fps=1)
    assert clip1 == target1

    clip2 = BitmapClip(
        [["AA", "AA"], ["BB", "BB"], ["CC", "CC"], ["DD", "DD"]], fps=1)

    clip3 = time_mirror(clip2)
    target3 = BitmapClip(
        [["DD", "DD"], ["CC", "CC"], ["BB", "BB"], ["AA", "AA"]], fps=1)
    assert clip3 == target3
Example #6
0
def test_time_symmetrize():
    clip = BitmapClip([["AA", "AA"], ["BB", "BB"], ["CC", "CC"]], fps=1)

    clip1 = time_symmetrize(clip)
    target1 = BitmapClip(
        [
            ["AA", "AA"],
            ["BB", "BB"],
            ["CC", "CC"],
            ["CC", "CC"],
            ["BB", "BB"],
            ["AA", "AA"],
        ],
        fps=1,
    )
    assert clip1 == target1
Example #7
0
def test_fadein():
    color_dict = {
        "I": (0, 0, 0),
        "R": (255, 0, 0),
        "G": (0, 255, 0),
        "B": (0, 0, 255),
        "W": (255, 255, 255),
    }
    clip = BitmapClip([["R"], ["G"], ["B"]], color_dict=color_dict, fps=1)

    clip1 = fadein(clip, 1)  # default initial color
    target1 = BitmapClip([["I"], ["G"], ["B"]], color_dict=color_dict, fps=1)
    assert clip1 == target1

    clip2 = fadein(clip, 1, initial_color=(255, 255, 255))  # different initial color
    target2 = BitmapClip([["W"], ["G"], ["B"]], color_dict=color_dict, fps=1)
    assert clip2 == target2
Example #8
0
def test_crop():
    # x: 0 -> 4, y: 0 -> 3 inclusive
    clip = BitmapClip([["ABCDE", "EDCBA", "CDEAB", "BAEDC"]], fps=1)

    clip1 = crop(clip)
    target1 = BitmapClip([["ABCDE", "EDCBA", "CDEAB", "BAEDC"]], fps=1)
    assert clip1 == target1

    clip2 = crop(clip, x1=1, y1=1, x2=3, y2=3)
    target2 = BitmapClip([["DC", "DE"]], fps=1)
    assert clip2 == target2

    clip3 = crop(clip, y1=2)
    target3 = BitmapClip([["CDEAB", "BAEDC"]], fps=1)
    assert clip3 == target3

    clip4 = crop(clip, x1=2, width=2)
    target4 = BitmapClip([["CD", "CB", "EA", "ED"]], fps=1)
    assert clip4 == target4

    # TODO x_center=1 does not perform correctly
    clip5 = crop(clip, x_center=2, y_center=2, width=3, height=3)
    target5 = BitmapClip([["ABC", "EDC", "CDE"]], fps=1)
    assert clip5 == target5

    clip6 = crop(clip, x_center=2, width=2, y1=1, y2=2)
    target6 = BitmapClip([["DC"]], fps=1)
    assert clip6 == target6
Example #9
0
def test_loop(util, video):
    clip = BitmapClip([["R"], ["G"], ["B"]], fps=1)

    clip1 = loop(clip, n=2)  # loop 2 times
    target1 = BitmapClip([["R"], ["G"], ["B"], ["R"], ["G"], ["B"]], fps=1)
    assert clip1 == target1

    clip2 = loop(clip, duration=8)  # loop 8 seconds
    target2 = BitmapClip(
        [["R"], ["G"], ["B"], ["R"], ["G"], ["B"], ["R"], ["G"]], fps=1)
    assert clip2 == target2

    clip3 = loop(clip).with_duration(5)  # infinite loop
    target3 = BitmapClip([["R"], ["G"], ["B"], ["R"], ["G"]], fps=1)
    assert clip3 == target3

    clip = video(start_time=0.2, end_time=0.3)  # 0.1 seconds long
    clip1 = loop(clip).with_duration(0.5)  # infinite looping
    clip1.write_videofile(os.path.join(util.TMP_DIR, "loop1.webm"))

    clip2 = loop(clip, duration=0.5)  # loop for 1 second
    clip2.write_videofile(os.path.join(util.TMP_DIR, "loop2.webm"))

    clip3 = loop(clip, n=3)  # loop 3 times
    clip3.write_videofile(os.path.join(util.TMP_DIR, "loop3.webm"))

    # Test audio looping
    clip = AudioClip(lambda t: np.sin(440 * 2 * np.pi * t) * (t % 1) + 0.5,
                     duration=2.5,
                     fps=44100)
    clip1 = clip.loop(2)
Example #10
0
def test_loop():
    clip = BitmapClip([["R"], ["G"], ["B"]], fps=1)

    clip1 = loop(clip, n=2)  # loop 2 times
    target1 = BitmapClip([["R"], ["G"], ["B"], ["R"], ["G"], ["B"]], fps=1)
    assert clip1 == target1

    clip2 = loop(clip, duration=8)  # loop 8 seconds
    target2 = BitmapClip(
        [["R"], ["G"], ["B"], ["R"], ["G"], ["B"], ["R"], ["G"]], fps=1)
    assert clip2 == target2

    clip3 = loop(clip).with_duration(5)  # infinite loop
    target3 = BitmapClip([["R"], ["G"], ["B"], ["R"], ["G"]], fps=1)
    assert clip3 == target3

    clip = get_test_video().subclip(0.2, 0.3)  # 0.1 seconds long
    clip1 = loop(clip).with_duration(0.5)  # infinite looping
    clip1.write_videofile(os.path.join(TMP_DIR, "loop1.webm"))

    clip2 = loop(clip, duration=0.5)  # loop for 1 second
    clip2.write_videofile(os.path.join(TMP_DIR, "loop2.webm"))

    clip3 = loop(clip, n=3)  # loop 3 times
    clip3.write_videofile(os.path.join(TMP_DIR, "loop3.webm"))

    # Test audio looping
    clip = AudioClip(lambda t: np.sin(440 * 2 * np.pi * t) * (t % 1) + 0.5,
                     duration=2.5,
                     fps=44100)
    clip1 = clip.loop(2)
    # TODO fix AudioClip.__eq__()
    # assert concatenate_audioclips([clip, clip]) == clip1

    close_all_clips(objects=locals())
Example #11
0
def test_freeze():
    clip = BitmapClip([["R"], ["G"], ["B"]], fps=1)  # 3 separate frames

    clip1 = freeze(clip, t=1, freeze_duration=1)
    target1 = BitmapClip([["R"], ["G"], ["G"], ["B"]], fps=1)
    assert clip1 == target1

    clip2 = freeze(clip, t="end", freeze_duration=1)
    target2 = BitmapClip([["R"], ["G"], ["B"], ["B"]], fps=1)
    assert clip2 == target2

    clip3 = freeze(clip, t=1, total_duration=4)
    target3 = BitmapClip([["R"], ["G"], ["G"], ["B"]], fps=1)
    assert clip3 == target3

    clip4 = freeze(clip, t="end", total_duration=4, padding_end=1)
    target4 = BitmapClip([["R"], ["G"], ["G"], ["B"]], fps=1)
    assert clip4 == target4
Example #12
0
def test_margin():
    clip = BitmapClip([["RRR", "RRR"], ["RRB", "RRB"]], fps=1)

    # Make sure that the default values leave clip unchanged
    clip1 = margin(clip)
    assert clip == clip1

    # 1 pixel black margin
    clip2 = margin(clip, margin_size=1)
    target = BitmapClip(
        [["OOOOO", "ORRRO", "ORRRO", "OOOOO"], ["OOOOO", "ORRBO", "ORRBO", "OOOOO"]],
        fps=1,
    )
    assert target == clip2

    # 1 pixel green margin
    clip3 = margin(clip, margin_size=1, color=(0, 255, 0))
    target = BitmapClip(
        [["GGGGG", "GRRRG", "GRRRG", "GGGGG"], ["GGGGG", "GRRBG", "GRRBG", "GGGGG"]],
        fps=1,
    )
    assert target == clip3
Example #13
0
def test_rotate_supported_PIL_kwargs(
    unsupported_kwargs,
    monkeypatch,
):
    """Test supported 'rotate' FX arguments by PIL version."""
    rotate_module = importlib.import_module("moviepy.video.fx.rotate")

    # patch supported kwargs data by PIL version
    new_PIL_rotate_kwargs_supported, min_version_by_kwarg_name = ({}, {})
    for kwarg, (
            kw_name,
            supported,
            min_version,
    ) in rotate_module.PIL_rotate_kwargs_supported.items():
        supported = kw_name not in unsupported_kwargs
        new_PIL_rotate_kwargs_supported[kwarg] = [
            kw_name, supported, min_version
        ]

        min_version_by_kwarg_name[kw_name] = ".".join(
            str(n) for n in min_version)

    monkeypatch.setattr(
        rotate_module,
        "PIL_rotate_kwargs_supported",
        new_PIL_rotate_kwargs_supported,
    )

    with pytest.warns(UserWarning) as record:
        BitmapClip([["R", "G", "B"]], fps=1).fx(
            rotate_module.rotate,
            45,
            bg_color=(10, 10, 10),
            center=(1, 1),
            translate=(1, 0),
        )

    # assert number of warnings
    assert len(record.list) == len(unsupported_kwargs)

    # assert messages contents
    messages = []
    for warning in record.list:
        messages.append(warning.message.args[0])

    for unsupported_kwarg in unsupported_kwargs:
        expected_message = (
            f"rotate '{unsupported_kwarg}' argument is not supported by your"
            " Pillow version and is being ignored. Minimum Pillow version"
            f" required: v{min_version_by_kwarg_name[unsupported_kwarg]}")
        assert expected_message in messages
Example #14
0
def test_rotate(angle_offset):
    # Run several times to ensure that adding 360 to rotation angles has no effect
    clip = BitmapClip([["AAAA", "BBBB", "CCCC"], ["ABCD", "BCDE", "CDEA"]], fps=1)

    clip1 = rotate(clip, 0 + angle_offset)
    target1 = BitmapClip([["AAAA", "BBBB", "CCCC"], ["ABCD", "BCDE", "CDEA"]], fps=1)
    assert clip1 == target1

    clip2 = rotate(clip, 90 + angle_offset)
    target2 = BitmapClip(
        [["ABC", "ABC", "ABC", "ABC"], ["DEA", "CDE", "BCD", "ABC"]], fps=1
    )
    assert clip2 == target2, clip2.to_bitmap()

    clip3 = rotate(clip, 180 + angle_offset)
    target3 = BitmapClip([["CCCC", "BBBB", "AAAA"], ["AEDC", "EDCB", "DCBA"]], fps=1)
    assert clip3 == target3

    clip4 = rotate(clip, 270 + angle_offset)
    target4 = BitmapClip(
        [["CBA", "CBA", "CBA", "CBA"], ["CBA", "DCB", "EDC", "AED"]], fps=1
    )
    assert clip4 == target4
Example #15
0
def test_speedx():
    clip = BitmapClip([["A"], ["B"], ["C"], ["D"]], fps=1)

    clip1 = speedx(clip, 0.5)  # 1/2x speed
    target1 = BitmapClip(
        [["A"], ["A"], ["B"], ["B"], ["C"], ["C"], ["D"], ["D"]], fps=1
    )
    assert clip1 == target1

    clip2 = speedx(clip, final_duration=8)  # 1/2x speed
    target2 = BitmapClip(
        [["A"], ["A"], ["B"], ["B"], ["C"], ["C"], ["D"], ["D"]], fps=1
    )
    assert clip2 == target2

    clip3 = speedx(clip, final_duration=12)  # 1/2x speed
    target3 = BitmapClip(
        [
            ["A"],
            ["A"],
            ["A"],
            ["B"],
            ["B"],
            ["B"],
            ["C"],
            ["C"],
            ["C"],
            ["D"],
            ["D"],
            ["D"],
        ],
        fps=1,
    )
    assert clip3 == target3

    clip4 = speedx(clip, 2)  # 2x speed
    target4 = BitmapClip([["A"], ["C"]], fps=1)
    assert clip4 == target4

    clip5 = speedx(clip, final_duration=2)  # 2x speed
    target5 = BitmapClip([["A"], ["C"]], fps=1)
    assert clip5 == target5

    clip6 = speedx(clip, 4)  # 4x speed
    target6 = BitmapClip([["A"]], fps=1)
    assert (
        clip6 == target6
    ), f"{clip6.duration} {target6.duration} {clip6.fps} {target6.fps}"
Example #16
0
def test_rotate(
    angle_offset,
    angle,
    unit,
    resample,
    translate,
    center,
    bg_color,
    expected_frames,
):
    """Check ``rotate`` FX behaviour against possible combinations of arguments."""
    original_frames = [["AAAA", "BBBB", "CCCC"], ["ABCD", "BCDE", "CDEA"]]

    # angles are defined in degrees, so convert to radians testing ``unit="rad"``
    if unit == "rad":
        if hasattr(angle, "__call__"):
            _angle = lambda t: math.radians(angle(0))
        else:
            _angle = math.radians(angle)
    else:
        _angle = angle
    clip = BitmapClip(original_frames, fps=1)

    kwargs = {
        "unit": unit,
        "resample": resample,
        "translate": translate,
        "center": center,
        "bg_color": bg_color,
    }
    if resample not in ["bilinear", "nearest", "bicubic"]:
        with pytest.raises(ValueError) as exc:
            clip.rotate(_angle, **kwargs)
        assert (
            "'resample' argument must be either 'bilinear', 'nearest' or 'bicubic'"
        ) == str(exc.value)
        return
    else:
        rotated_clip = clip.rotate(_angle, **kwargs)

    expected_clip = BitmapClip(expected_frames, fps=1)
    assert rotated_clip.to_bitmap() == expected_clip.to_bitmap()
Example #17
0
def test_freeze(t, freeze_duration, total_duration, padding_end, output_frames):
    input_frames = ["R", "G", "B"]
    clip_duration = len(input_frames)

    # create BitmapClip with predefined set of colors, during 1 second each one
    clip = BitmapClip([list(color) for color in input_frames], fps=1).with_duration(
        clip_duration
    )

    # build kwargs passed to `freeze`
    possible_kwargs = {
        "t": t,
        "freeze_duration": freeze_duration,
        "total_duration": total_duration,
        "padding_end": padding_end,
    }
    kwargs = {
        kw_name: kw_value
        for kw_name, kw_value in possible_kwargs.items()
        if kw_value is not None
    }

    # freeze clip
    if hasattr(output_frames, "__traceback__"):
        with pytest.raises(output_frames):
            freeze(clip, **kwargs)
        return
    else:
        freezed_clip = freeze(clip, **kwargs)

    # assert new duration
    expected_freeze_duration = (
        freeze_duration
        if freeze_duration is not None
        else total_duration - clip_duration
    )
    assert freezed_clip.duration == clip_duration + expected_freeze_duration

    # assert colors are the expected
    for i, color in enumerate(freezed_clip.iter_frames()):
        expected_color = list(BitmapClip.DEFAULT_COLOR_DICT[output_frames[i]])
        assert list(color[0][0]) == expected_color
Example #18
0
def test_even_size():
    clip1 = BitmapClip([["ABC", "BCD"]], fps=1)  # Width odd
    clip1even = even_size(clip1)
    target1 = BitmapClip([["AB", "BC"]], fps=1)
    assert clip1even == target1

    clip2 = BitmapClip([["AB", "BC", "CD"]], fps=1)  # Height odd
    clip2even = even_size(clip2)
    target2 = BitmapClip([["AB", "BC"]], fps=1)
    assert clip2even == target2

    clip3 = BitmapClip([["ABC", "BCD", "CDE"]], fps=1)  # Width and height odd
    clip3even = even_size(clip3)
    target3 = BitmapClip([["AB", "BC"]], fps=1)
    assert clip3even == target3
Example #19
0
def test_rotate(
    PIL_installed,
    angle_offset,
    angle,
    unit,
    resample,
    translate,
    center,
    bg_color,
    expected_frames,
    monkeypatch,
):
    """Check ``rotate`` FX behaviour against possible combinations of arguments."""
    original_frames = [["AAAA", "BBBB", "CCCC"], ["ABCD", "BCDE", "CDEA"]]

    # angles are defined in degrees, so convert to radians testing ``unit="rad"``
    if unit == "rad":
        if hasattr(angle, "__call__"):
            _angle = lambda t: math.radians(angle(0))
        else:
            _angle = math.radians(angle)
    else:
        _angle = angle
    clip = BitmapClip(original_frames, fps=1)

    kwargs = {
        "unit": unit,
        "resample": resample,
        "translate": translate,
        "center": center,
        "bg_color": bg_color,
    }
    if resample not in ["bilinear", "nearest", "bicubic"]:
        with pytest.raises(ValueError) as exc:
            clip.rotate(_angle, **kwargs)
        assert (
            "'resample' argument must be either 'bilinear', 'nearest' or 'bicubic'"
        ) == str(exc.value)
        return

    # if the scenario implies that PIL is not installed, monkeypatch the
    # module in which 'rotate' function resides
    if not PIL_installed:
        rotate_module = importlib.import_module("moviepy.video.fx.rotate")
        monkeypatch.setattr(rotate_module, "Image", None)
        rotate_func = rotate_module.rotate
    else:
        rotate_func = rotate

    # resolve the angle, because if it is a multiple of 90, the rotation
    # can be computed event without an available PIL installation
    if hasattr(_angle, "__call__"):
        _resolved_angle = _angle(0)
    else:
        _resolved_angle = _angle
    if unit == "rad":
        _resolved_angle = math.degrees(_resolved_angle)

    if not PIL_installed and ((_resolved_angle % 90 != 0) or center
                              or translate or bg_color):
        with pytest.raises(ValueError) as exc:
            rotated_clip = clip.fx(rotate_func, _angle, **kwargs)

        assert (
            'Without "Pillow" installed, only angles that are a multiple of 90'
        ) in str(exc.value)

    else:
        rotated_clip = clip.fx(rotate_func, _angle, **kwargs)
        expected_clip = BitmapClip(expected_frames, fps=1)

        assert rotated_clip.to_bitmap() == expected_clip.to_bitmap()
Example #20
0
def test_mirror_y():
    clip = BitmapClip([["AB", "CD"]], fps=1)
    clip1 = mirror_y(clip)
    target = BitmapClip([["CD", "AB"]], fps=1)
    assert clip1 == target
Example #21
0
def test_mirror_x():
    clip = BitmapClip([["AB", "CD"]], fps=1)
    clip1 = mirror_x(clip)
    target = BitmapClip([["BA", "DC"]], fps=1)
    assert clip1 == target
Example #22
0
def test_blackwhite():
    # Create black/white spectrum ``bw_color_dict`` to compare against it.
    # Colors after ``blackwhite`` FX must be inside this dictionary
    # Note: black/white spectrum is made of colors with same numbers
    # [(0, 0, 0), (1, 1, 1), (2, 2, 2)...]
    bw_color_dict = {}
    for num in range(0, 256):
        bw_color_dict[chr(num + 255)] = (num, num, num)
    color_dict = bw_color_dict.copy()
    # update dictionary with default BitmapClip color_dict values
    color_dict.update(BitmapClip.DEFAULT_COLOR_DICT)

    # add row with random colors in b/w spectrum
    random_row = ""
    for num in range(512, 515):
        # use unique unicode representation for each color
        char = chr(num)
        random_row += char

        # random colors in the b/w spectrum
        color_dict[char] = tuple(random.randint(0, 255) for i in range(3))

    # clip converted below to black/white
    clip = BitmapClip([["RGB", random_row]], color_dict=color_dict, fps=1)

    # for each possible ``preserve_luminosity`` boolean argument value
    for preserve_luminosity in [True, False]:
        # default argument (``RGB=None``)
        clip_bw = blackwhite(clip, preserve_luminosity=preserve_luminosity)

        bitmap = clip_bw.to_bitmap()
        assert bitmap

        for i, row in enumerate(bitmap[0]):
            for char in row:
                # all characters returned by ``to_bitmap`` are in the b/w spectrum
                assert char in bw_color_dict

                if i == 0:  # pure "RGB" colors are converted to [85, 85, 85]
                    assert char == row[0]  # so are equal

        # custom random ``RGB`` argument
        clip_bw_custom_rgb = blackwhite(
            clip,
            RGB=(random.randint(0, 255), 0, 0),
            preserve_luminosity=preserve_luminosity,
        )
        bitmap = clip_bw_custom_rgb.to_bitmap()
        for i, row in enumerate(bitmap[0]):
            for i2, char in enumerate(row):
                # all characters returned by ``to_bitmap`` are in the b/w spectrum
                assert char in bw_color_dict

                # for clip "RGB" row, two latest converted colors are equal
                if i == 0 and i2 > 0:
                    assert char == row[1] and char == row[2]

        # ``RGB="CRT_phosphor"`` argument
        clip_bw_crt_phosphor = blackwhite(
            clip, RGB="CRT_phosphor", preserve_luminosity=preserve_luminosity)
        bitmap = clip_bw_crt_phosphor.to_bitmap()
        assert bitmap
        for row in bitmap[0]:
            for char in row:
                # all characters returned by ``to_bitmap`` are in the b/w spectrum
                assert char in bw_color_dict