?

Log in

No account? Create an account

GIF-less animations

« previous entry | next entry »
Jan. 2nd, 2018 | 03:29 pm

You may find yourself wanting to make an animation, say for use on Telegram. You may also find yourself working in GIMP, only to the find that that program (even in the latest preview release, 2.9.8, which came out in mid-December 2017) appears to lack any support for saving animations in any format other than GIF. Which wouldn't be so bad if it weren't for the fact that the GIF file format is more than 30 years old and (crucially) lacks support for truecolor images.

GIMP also has no support for either MNG or APNG so far as I know; there's an APNG plugin, but it's not working in the current stable GIMP version (2.8.22), at least not for me.

There's some ways out. First of all, there's a tool called APNG Assembler that does exactly what it says on the tin: it takes a bunch of frames and converts them to a single APNG. (There's also a matching APNG Disassembler and APNG Optimizer.) It's straightforward enough to use and works as intended.

The only downside is that GIMP also seems to lack any ability to export all layers of an image to individual files as once, so you'll have to save every frame of your animation individually. (The best way to do this that I've found is to Shift-click the "Eye" icon in the Layers dialog for each layer in turn to make only that layer visible, then export as normal; the image will be exported as you see it, i.e. only the visible layer. This works reasonably well if you only have a small number of animation frames.)

Of course APNG doesn't work for Telegram, but MPEG-4 does. GIMP also cannot handle that, but ffmpeg can; there's a terse little tutorial here. The only snag I ran into was the following:

$ ffmpeg -r 10 -f image2 -s 800x1033 -i frame%d.png -vcodec libx264 -crf 25 -pix_fmt yuv420p test.mp4
[...]
Input #0, image2, from 'frame%d.png':
  Duration: 00:00:00.70, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgba(pc), 800x1033 [SAR 2835:2835 DAR 800:1033], 10 fps, 10 tbr, 10 tbn, 10 tbc
[libx264 @ 02cbe0e0] height not divisible by 2 (800x1033)
Output #0, mp4, to 'test.mp4':
    Stream #0:0: Video: h264, none, q=2-31, 128 kb/s, SAR 1:1 DAR 0:0, 10 fps
    Metadata:
      encoder         : Lavc56.60.100 libx264
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
$ 

Hardly an informative error message; it turns out that the problem is the -pix_fmt switch, though. Leaving that out works as intended:

$ ffmpeg -r 10 -f image2 -s 800x1033 -i frame%d.png -vcodec libx264 -crf 25 test2.mp4
[...]
Input #0, image2, from 'frame%d.png':
  Duration: 00:00:00.70, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgba(pc), 800x1033 [SAR 2835:2835 DAR 800:1033], 10 fps, 10 tbr, 10 tbn, 10 tbc
No pixel format specified, yuv444p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264 @ 0499de80] using SAR=1/1
[libx264 @ 0499de80] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0499de80] profile High 4:4:4 Predictive, level 3.1, 4:4:4 8-bit
[libx264 @ 0499de80] 264 - core 148 r2638 7599210 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http://www.videolan.org/x264.html - 
options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1
trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=4 threads=12 lookahead_threads=2 sliced_threads=0 nr=0
decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0
weightp=2 keyint=250 keyint_min=10 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=25.0 qcomp=0.60 qpmin=0 qpmax=69
qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'test2.mp4':
  Metadata:
    encoder         : Lavf56.40.101
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv444p, 800x1033 [SAR 1:1 DAR 800:1033], q=-1--1, 10 fps, 10240 tbn, 10 tbc
    Metadata:
      encoder         : Lavc56.60.100 libx264
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
frame=    7 fps=0.0 q=-1.0 Lsize=     140kB time=00:00:00.50 bitrate=2292.9kbits/s
video:139kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.646833%
[libx264 @ 0499de80] frame I:1     Avg QP:23.21  size: 87998
[libx264 @ 0499de80] frame P:4     Avg QP:24.84  size:  9412
[libx264 @ 0499de80] frame B:2     Avg QP:26.30  size:  8026
[libx264 @ 0499de80] consecutive B-frames: 42.9% 57.1%  0.0%  0.0%
[libx264 @ 0499de80] mb I  I16..4:  8.2% 68.4% 23.4%
[libx264 @ 0499de80] mb P  I16..4:  2.7% 12.9%  2.6%  P16..4: 12.3%  4.6%  2.2%  0.0%  0.0%    skip:62.8%
[libx264 @ 0499de80] mb B  I16..4:  1.1%  5.5%  1.8%  B16..8: 15.8%  5.0%  1.4%  direct: 2.0%  skip:67.5%  L0:30.9% L1:66.6% BI: 2.5%
[libx264 @ 0499de80] 8x8 transform intra:69.1% inter:73.4%
[libx264 @ 0499de80] coded y,u,v intra: 54.6% 27.4% 27.4% inter: 7.0% 1.5% 1.9%
[libx264 @ 0499de80] i16 v,h,dc,p: 23% 58%  4% 15%
[libx264 @ 0499de80] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 13% 43% 13%  3%  4%  4%  7%  4%  7%
[libx264 @ 0499de80] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 17% 18% 12%  6% 10% 12% 11%  7%  7%
[libx264 @ 0499de80] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0499de80] ref P L0: 62.0% 11.9% 18.9%  7.2%
[libx264 @ 0499de80] ref B L0: 80.8% 19.2%
[libx264 @ 0499de80] kb/s:1619.39
$ 

So, to recap: export your layers, and use ffmpeg to assemble them. There's likely GUI frontends for ffmpeg, and perhaps there's a more convenient way of exporting an image into one file per layer; if you know of either, let me know.

Link | Leave a comment |

Comments {8}

Transitioning into liminal space

(no subject)

from: stormdog
date: Jan. 2nd, 2018 04:00 pm (UTC)
Link

I'm sorry. I read your first sentence and all I could think of was:

"You may find yourself wanting to make an animation.
You may find yourself in another part of the world.
You may find yourself behind the wheel of a large automobile.
And you may ask yourself; how did I get here?"

Reply | Thread

Schnee

(no subject)

from: schnee
date: Jan. 2nd, 2018 08:43 pm (UTC)
Link

"You may find yourself wanting to make an animation.
You may find yourself in another part of the world.
You may find yourself behind the wheel of a large automobile.
And you may ask yourself; how did I get here?"


"It is very dark.
You are likely to be eaten by a grue..."

Reply | Parent | Thread

Transitioning into liminal space

(no subject)

from: stormdog
date: Jan. 2nd, 2018 08:51 pm (UTC)
Link

Is that why this place looks like a maze of twisty little passages, all alike? I thought that was because I work in a hospital now.

Reply | Parent | Thread

Schnee

(no subject)

from: schnee
date: Jan. 2nd, 2018 09:44 pm (UTC)
Link

Ah, but hospitals are a grue's natural habitat, didn't you know?

Reply | Parent | Thread

Transitioning into liminal space

(no subject)

from: stormdog
date: Jan. 2nd, 2018 10:09 pm (UTC)
Link

Good thing I usually have the headlight for my bike with me!

Reply | Parent | Thread

moonhare

(no subject)

from: mondhasen
date: Jan. 2nd, 2018 10:43 pm (UTC)
Link

*grin* I was singing that as well!

Reply | Parent | Thread

Transitioning into liminal space

(no subject)

from: stormdog
date: Jan. 2nd, 2018 10:57 pm (UTC)
Link

Yay!

Reply | Parent | Thread

Schnee

(no subject)

from: schnee
date: Jan. 2nd, 2018 11:00 pm (UTC)
Link

GMTA!

Reply | Parent | Thread