from PIL import Image, ImageEnhance
import numpy as np
import imageio
import os

def create_3d_flip(front_path, back_path, output_path, frames=72, fps=30):
    """
    Creates a 3D flipping animation that switches between front and back images
    during rotation for a realistic 3D effect, preserving transparency in the GIF.
    """
    # Load both front and back images
    front_logo = Image.open(front_path).convert('RGBA')
    back_logo = Image.open(back_path).convert('RGBA')
    
    # Ensure both images are the same size
    if front_logo.size != back_logo.size:
        raise ValueError("Front and back images must have the same dimensions.")
    
    width, height = front_logo.size
    
    # Add padding for the rotation
    canvas_size = (int(width * 1.3), int(height * 1.3))
    frames_list = []
    
    for i in range(frames):
        # Calculate angle for this frame
        angle = (i / frames) * 360
        
        # Create a new transparent canvas
        canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
        
        # Determine which logo to use based on rotation angle
        if 90 <= angle < 270:
            current_logo = back_logo
            # Adjust angle for back side to maintain correct rotation direction
            display_angle = angle - 180
        else:
            current_logo = front_logo
            display_angle = angle
        
        # Calculate scaling factor for perspective effect
        scale_factor = 0.7 + 0.3 * abs(np.cos(np.radians(angle)))
        
        # Calculate new dimensions with perspective
        new_width = int(width * scale_factor)
        new_height = int(height * scale_factor)
        
        # Resize the logo
        frame_logo = current_logo.resize((new_width, new_height), Image.LANCZOS)
        
        # Rotate the logo
        frame_logo = frame_logo.rotate(display_angle, expand=True, resample=Image.BICUBIC)
        
        # Calculate position to center the logo
        paste_x = (canvas_size[0] - frame_logo.width) // 2
        paste_y = (canvas_size[1] - frame_logo.height) // 2
        
        # Add subtle brightness variation based on rotation
        enhancer = ImageEnhance.Brightness(frame_logo)
        brightness_factor = 0.8 + 0.2 * abs(np.cos(np.radians(angle)))
        frame_logo = enhancer.enhance(brightness_factor)
        
        # Paste the logo onto the canvas with its alpha channel as mask
        canvas.paste(frame_logo, (paste_x, paste_y), frame_logo)
        
        # Convert the canvas to a numpy array while preserving RGBA
        frame_array = np.array(canvas)
        frames_list.append(frame_array)
    
    # Save frames as GIF with transparency using ImageIO
    # Convert list to a numpy array
    frames_np = np.array(frames_list)
    
    # Create output directory if it doesn't exist
    os.makedirs(os.path.dirname(output_path), exist_ok=True)
    
    # Save using imageio with transparency
    imageio.mimsave(
        output_path,
        frames_np,
        format='GIF',
        duration=1/fps,
        loop=0,
        disposal=2,
        transparency=0  # This sets the first color in the palette as transparent
    )
    
    print(f"3D flipping animation saved to {output_path}")

# Usage
front_path = "/root/auto/img/transparent.png"
back_path = "/root/auto/img/rev_logo.png"
output_path = "/root/auto/output/spin_effect.gif"

# Create the animation
create_3d_flip(front_path, back_path, output_path)
(final) {24-10-29 18:55}localhost:~/auto root# python3 spin_effect.py
Traceback (most recent call last):
  File "/root/auto/spin_effect.py", line 96, in <module>
    create_3d_flip(front_path, back_path, output_path)
  File "/root/auto/spin_effect.py", line 78, in create_3d_flip
    imageio.mimsave(
  File "/root/auto/final/lib/python3.12/site-packages/imageio/v2.py", line 494, in mimwrite
    with imopen(uri, "wI", **imopen_args) as file:
  File "/root/auto/final/lib/python3.12/site-packages/imageio/core/v3_plugin_api.py", line 367, in __exit__
    self.close()
  File "/root/auto/final/lib/python3.12/site-packages/imageio/plugins/pillow.py", line 144, in close
    self._flush_writer()
  File "/root/auto/final/lib/python3.12/site-packages/imageio/plugins/pillow.py", line 485, in _flush_writer
    primary_image.save(self._request.get_file(), **self.save_args)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/Image.py", line 2605, in save
    save_handler(self, fp, filename)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/GifImagePlugin.py", line 774, in _save_all
    _save(im, fp, filename, save_all=True)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/GifImagePlugin.py", line 787, in _save
    if not save_all or not _write_multiple_frames(im, fp, palette):
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/auto/final/lib/python3.12/site-packages/PIL/GifImagePlugin.py", line 700, in _write_multiple_frames
    background_im.putpalette(im_frames[0].im.palette)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/Image.py", line 2103, in putpalette
    self.load()  # install new palette
    ^^^^^^^^^^^
  File "/root/auto/final/lib/python3.12/site-packages/PIL/Image.py", line 909, in load
    self.im.putpalette(self.palette.mode, mode, arr)
ValueError: invalid palette size
Exception ignored in: <function PluginV3.__del__ at 0x7d982baa20>
Traceback (most recent call last):
  File "/root/auto/final/lib/python3.12/site-packages/imageio/core/v3_plugin_api.py", line 370, in __del__
    self.close()
  File "/root/auto/final/lib/python3.12/site-packages/imageio/plugins/pillow.py", line 144, in close
    self._flush_writer()
  File "/root/auto/final/lib/python3.12/site-packages/imageio/plugins/pillow.py", line 485, in _flush_writer
    primary_image.save(self._request.get_file(), **self.save_args)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/Image.py", line 2605, in save
    save_handler(self, fp, filename)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/GifImagePlugin.py", line 774, in _save_all
    _save(im, fp, filename, save_all=True)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/GifImagePlugin.py", line 787, in _save
    if not save_all or not _write_multiple_frames(im, fp, palette):
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/auto/final/lib/python3.12/site-packages/PIL/GifImagePlugin.py", line 700, in _write_multiple_frames
    background_im.putpalette(im_frames[0].im.palette)
  File "/root/auto/final/lib/python3.12/site-packages/PIL/Image.py", line 2103, in putpalette
    self.load()  # install new palette
    ^^^^^^^^^^^
  File "/root/auto/final/lib/python3.12/site-packages/PIL/Image.py", line 909, in load
    self.im.putpalette(self.palette.mode, mode, arr)
ValueError: invalid palette size