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

Animated GIF corruption + size increase #1024

Closed
miketaylr opened this issue Apr 28, 2016 · 10 comments
Closed

Animated GIF corruption + size increase #1024

miketaylr opened this issue Apr 28, 2016 · 10 comments

Comments

@miketaylr
Copy link
Member

If you upload an animated GIF, it's being corrupted at some level.

Compare the source:

redbox

And the uploaded file:

687474703a2f2f73746167696e672e776562636f6d7061742e636f6d2f75706c6f6164732f323031362f342f39346361626634392d333539322d343836312d613936392d3637353635303932363936362e676966

Also the original file-size was 2.7MB, the corrupted version is 5.6MB 😮

@karlcow something you want to tackle?

@miketaylr
Copy link
Member Author

I just looked at a recent PNG I uploaded:

Original size: 1.2MB
Uploaded size: 963kb.

Very cool.

@miketaylr
Copy link
Member Author

@karlcow
Copy link
Member

karlcow commented Apr 28, 2016

The corrupted GIF issues. yes this is known. We discussed about it already.
see #710 (comment)

And you can see my discussion with Pillow owners
python-pillow/Pillow#1717

@karlcow
Copy link
Member

karlcow commented Apr 28, 2016

We also discussed it here
karlcow@3240856

@karlcow karlcow closed this as completed Apr 28, 2016
@karlcow
Copy link
Member

karlcow commented Apr 28, 2016

Note that I can try to solve it on Pillow side, but that will take a bit of time, because I think it's quite a complex issue with color encoding compression, etc.

I wonder if for animated gif, we could convert them to compressed mp4 movies. as we are able to detect them.

@karlcow
Copy link
Member

karlcow commented Apr 28, 2016

@miketaylr Oh! http://zulko.github.io/moviepy/

Let's test something with that.

→ mkvirtualenv -a /Users/karl/code/testingstuff/ testing
New python executable in testing/bin/python
Installing setuptools, pip, wheel...wdone.
Setting project for testing to /Users/karl/code/testingstuff
(testing)11:41:20 ~/code/testingstuff
→ pip install moviepy
Collecting moviepy
  Downloading moviepy-0.2.2.11.tar.gz (107kB)
    100% |████████████████████████████████| 110kB 535kB/s 
Collecting numpy (from moviepy)
  Downloading numpy-1.11.0.tar.gz (4.2MB)
    100% |████████████████████████████████| 4.2MB 106kB/s 
Collecting decorator (from moviepy)
  Downloading decorator-4.0.9-py2.py3-none-any.whl
Collecting imageio (from moviepy)
  Downloading imageio-1.5-cp26.cp27.cp33.cp34.cp35-none-macosx_10_5_x86_64.macosx_10_6_intel.whl (4.8MB)
    100% |████████████████████████████████| 4.8MB 97kB/s 
Collecting tqdm (from moviepy)
  Downloading tqdm-4.5.0-py2.py3-none-any.whl
Building wheels for collected packages: moviepy, numpy
  Running setup.py bdist_wheel for moviepy
  Stored in directory: /Users/karl/Library/Caches/pip/wheels/ba/fa/af/be4051961aa23c8566906e9a3bd5f7bb57ac2c3f3c43f09dbc
  Running setup.py bdist_wheel for numpy
  Stored in directory: /Users/karl/Library/Caches/pip/wheels/d9/cc/5c/f60303cc48ac18e6bd359aa88e4fa50e8bd88fc7e9f001cfd8
Successfully built moviepy numpy
Installing collected packages: numpy, decorator, imageio, tqdm, moviepy
Successfully installed decorator-4.0.9 imageio-1.5 moviepy-0.2.2.11 numpy-1.11.0 tqdm-4.5.0
You are using pip version 7.1.2, however version 8.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(testing)11:44:18 ~/code/testingstuff
→ pip install --upgrade pip
Collecting pip
  Downloading pip-8.1.1-py2.py3-none-any.whl (1.2MB)
    100% |████████████████████████████████| 1.2MB 326kB/s 
Installing collected packages: pip
  Found existing installation: pip 7.1.2
    Uninstalling pip-7.1.2:
      Successfully uninstalled pip-7.1.2
Successfully installed pip-8.1.1
(testing)11:58:06 ~/code/testingstuff
→ python
Python 2.7.10 (default, Oct 23 2015, 19:19:21) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

Then onto the interesting stuff.

>>> import moviepy.editor as mp
Imageio: 'ffmpeg.osx' was not found on your computer; downloading it now.
Error while fetching file: ('The read operation timed out',).
Error while fetching file: ('The read operation timed out',).
Error while fetching file: ('The read operation timed out',).
Error while fetching file: ('The read operation timed out',).
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/moviepy/editor.py", line 22, in <module>
    from .video.io.VideoFileClip import VideoFileClip
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/moviepy/video/io/VideoFileClip.py", line 3, in <module>
    from moviepy.video.VideoClip import VideoClip
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/moviepy/video/VideoClip.py", line 20, in <module>
    from .io.ffmpeg_writer import ffmpeg_write_image, ffmpeg_write_video
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/moviepy/video/io/ffmpeg_writer.py", line 15, in <module>
    from moviepy.config import get_setting
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/moviepy/config.py", line 38, in <module>
    FFMPEG_BINARY = get_exe()
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/imageio/plugins/ffmpeg.py", line 52, in get_exe
    exe = get_remote_file('ffmpeg/' + FNAME_PER_PLATFORM[plat])
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/imageio/core/fetching.py", line 98, in get_remote_file
    _fetch_file(url, filename)
  File "/Users/karl/.virtualenvs/testing/lib/python2.7/site-packages/imageio/core/fetching.py", line 154, in _fetch_file
    os.path.basename(file_name))
IOError: Unable to download 'ffmpeg.osx'. Perhaps there is a no internet connection? If there is, please report this problem.

Rha let's pull the thread.

→  brew install FFmpeg
==> Installing dependencies for ffmpeg: x264, lame, libvo-aacenc, xvid
==> Installing ffmpeg dependency: x264
==> Downloading https://homebrew.bintray.com/bottles/x264-r2555.el_capitan.bottle.tar.gz
######################################################################## 100,0%
==> Pouring x264-r2555.el_capitan.bottle.tar.gz
🍺  /usr/local/Cellar/x264/r2555: 9 files, 3,3M
==> Installing ffmpeg dependency: lame
==> Downloading https://homebrew.bintray.com/bottles/lame-3.99.5.el_capitan.bottle.1.tar.gz
######################################################################## 100,0%
==> Pouring lame-3.99.5.el_capitan.bottle.1.tar.gz
🍺  /usr/local/Cellar/lame/3.99.5: 25 files, 2,2M
==> Installing ffmpeg dependency: libvo-aacenc
==> Downloading https://homebrew.bintray.com/bottles/libvo-aacenc-0.1.3.el_capitan.bottle.tar.gz
######################################################################## 100,0%
==> Pouring libvo-aacenc-0.1.3.el_capitan.bottle.tar.gz
🍺  /usr/local/Cellar/libvo-aacenc/0.1.3: 15 files, 336K
==> Installing ffmpeg dependency: xvid
==> Downloading https://homebrew.bintray.com/bottles/xvid-1.3.4.el_capitan.bottle.tar.gz
######################################################################## 100,0%
==> Pouring xvid-1.3.4.el_capitan.bottle.tar.gz
🍺  /usr/local/Cellar/xvid/1.3.4: 9 files, 1,3M
==> Installing ffmpeg
==> Downloading https://homebrew.bintray.com/bottles/ffmpeg-2.8.el_capitan.bottle.tar.gz
######################################################################## 100,0%
==> Pouring ffmpeg-2.8.el_capitan.bottle.tar.gz
==> Caveats
FFmpeg has been built without libfaac for licensing reasons;
libvo-aacenc is used by default.
To install with libfaac, you can:
  brew reinstall ffmpeg --with-faac

You can also use the experimental FFmpeg encoder, libfdk-aac, or
libvo_aacenc to encode AAC audio:
  ffmpeg -i input.wav -c:a aac -strict experimental output.m4a
Or:
  brew reinstall ffmpeg --with-fdk-aac
  ffmpeg -i input.wav -c:a libfdk_aac output.m4a
==> Summary
🍺  /usr/local/Cellar/ffmpeg/2.8: 210 files, 45M

Let's go back to python.

>>> import moviepy.editor as mp
Imageio: 'ffmpeg.osx' was not found on your computer; downloading it now.
Error while fetching file: ('The read operation timed out',).
Error while fetching file: ('The read operation timed out',).
Error while fetching file: ('The read operation timed out',).
Try 4. Download from https://github.com/imageio/imageio-binaries/raw/master/ffmpeg/ffmpeg.osx (28.8 MB)
Downloading: 30241064/30241064 bytes (100.0%)
  Done
File saved as /Users/karl/Library/Application Support/imageio/ffmpeg/ffmpeg.osx.
>>> movie_gif = mp.VideoFileClip("/Users/karl/Desktop/animated.gif")
>>> movie_gif.write_videofile("/Users/karl/Desktop/animated.webm")
[MoviePy] >>>> Building video /Users/karl/Desktop/animated.webm
[MoviePy] Writing video /Users/karl/Desktop/animated.webm
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 104.60it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: /Users/karl/Desktop/animated.webm 

OK the conversion worked! Without issues.
Let's see on the side of filesystem

ls -lh ~/Desktop/animated* | awk '{print $5, $9}'
# original
309K /Users/karl/Desktop/animated.gif
# Movie by moviepy
105K /Users/karl/Desktop/animated.webm
# Saved by pillow
707K /Users/karl/Desktop/animated_save_all.gif

@karlcow karlcow reopened this Apr 28, 2016
@karlcow
Copy link
Member

karlcow commented Apr 28, 2016

Just to be more explicit. Just the 3 lines of code.

import moviepy.editor as mp
movie_gif = mp.VideoFileClip("/Users/karl/Desktop/animated.gif")
movie_gif.write_videofile("/Users/karl/Desktop/animated.webm")

@miketaylr
Copy link
Member Author

We also discussed it here

Yeah, I remember that. I thought the idea was that we weren't going to touch animated GIFs with Pillow, to prevent the corruption. But I misunderstood, because just saving the image (via Image.save() ruins it.

(I guess my bad for not catching this at review.)

Another option might be detect if it's animated via Pillow, then save the original file manually via File.write().

@karlcow for the mp4 approach, do you have a sense of how long it takes to convert? I see you used webm, but Safari can't play those (or Edge currently), so probably not ideal. If it's fast, this seems cool. If it's slow maybe we skip Pillow for animated GIFs like mentioned above.

@karlcow
Copy link
Member

karlcow commented Apr 29, 2016

Yeah good points. Probably slow.

>>> timeit.timeit('import moviepy.editor as mp; movie_gif = mp.VideoFileClip("/Users/karl/Desktop/animated.gif"); movie_gif.write_videofile("/Users/karl/Desktop/animated.mp4", verbose=False)', number=10)
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 1001.18it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 1093.55it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 1105.09it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 966.25it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 1054.83it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 1025.64it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 961.58it/s]
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 972.44it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 1020.62it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 44/44 [00:00<00:00, 1054.83it/s]
1.6520440578460693

Around 1.6s to 1.7s

@miketaylr
Copy link
Member Author

Let's not fix this. 💣

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants