manim icon indicating copy to clipboard operation
manim copied to clipboard

Flipping does not work as expected for ImageMobject

Open UncraftedName opened this issue 3 years ago • 3 comments

Description of bug / unexpected behavior

Attempting to flip a ImageMobject across an axis does not seem to behave correctly. Flipping across the UP axis acts the same as a 180° rotation, while flipping across the RIGHT axis does nothing.

How to reproduce the issue

class Main(Scene):
    def construct(self):
        imgs = [ImageMobject("thinking.png").scale(0.1) for i in range(4)]
        self.add(Group(
            imgs[0],
            imgs[1].flip(),
            imgs[2].rotate(PI, UP),
            imgs[3].apply_matrix([[-1, 0], [0, 1]])
        ).arrange(RIGHT))

Additional media files

Images/GIFs

unknown (2)

Additional comments

The only way I have figured out to flip images across a single axis so far is to edit the pixel array like so:

img.pixel_array = np.fliplr(img.pixel_array)  # for horizontal
img.pixel_array = np.flipud(img.pixel_array)  # for vertical

UncraftedName avatar Jan 01 '22 21:01 UncraftedName

Just looked into this a bit. The proper way of fixing this would be to adapt the implementation in Camera.display_image_mobject -- basically, ImageMobjects are placed by specifying the coordinates of the upper left, upper right, and lower left corner (in ImageMobject.points). Manim is able to handle the case where the lower left corner is higher than the upper right corner (i.e., a flip along the horizontal axis), but curiously not when the upper right corner is left of the upper left corner (vertical flip).

behackl avatar Jan 05 '22 15:01 behackl

I believe the problem mentioned by @behackl also occurs frequently in ThreeDScenes and leads to a rather comical effect. When an image is part of a ThreeDScene the flipping happens naturally during rotations causing the image to distort and flip wildly.

class ImageIn3D(ThreeDScene):
    def construct(self):
        image = ImageMobject(
            np.uint8(np.random.randint(256, size=(256, 256)))
        )
        image.rotate_about_origin(PI/4, axis=np.array([0., 1., 0.]), axes=[])
        image.shift(3*RIGHT)
        self.set_camera_orientation(phi=PI/3, theta=PI/4)
        self.add(Cube(fill_opacity=1.0))
        self.add(image)
        self.begin_ambient_camera_rotation(rate=PI/2)
        self.wait(4)
        self.stop_ambient_camera_rotation()

ImageIn3D

hennels avatar Mar 15 '22 04:03 hennels

I believe this issue was fixed for the OpenGL renderer with #2534 as seen below. The distortion shown above and the flipping issue mentioned earlier seem to work now when OpenGL is used. The issues still exist with Cairo.

ImageIn3D2

hennels avatar Apr 28 '22 03:04 hennels