about summary refs log tree commit diff homepage
path: root/blog/gifrip.md
blob: dfb9353f46111cab47c49b4342b656aad00e740b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
+++
rss = "How to make GIF files from videos"
date = Date(2023, 03, 16)
tags = ["fun", "recipe"]
+++

# Artisanal GIF Ripping

!!! note "Pronounciation"

    /dʒɪf/ is the format, /ɡɪf/ is the handball club in Eskilstuna, Sweden.

GIF, *the* graphics interchange format, is probably the most [inefficient]
representation for animated images in quality/size that is widespread today.
However, it does live up to its name, being also the most portable format
for animated graphics exchange.  If a device has a color display
and is connected to the Internet, tis likely to support GIF out of the box.

Like with incandescent light bulbs, it'd be wasteful to have not switched
to more efficient alternatives, though GIF still has its charms.  Not having
to worry about codec compatibility is one thing, the nostalgia induced
by the `.gif` file extension is another.  For years, I got an *Internet* folder
full of those (along with still images and short videos) for offline viewing,
shitposting and reaction.

More recently, I [began][hyper] [to][milos] [make][grenade]
[my][tron] [own][potato] [animated][] [images][nf]
and take pride in them.  This tutorial will step-by-step
lay out my process in cutting out a high-quality GIF
from a video, so [you can be just like me][role model]!

\toc

## Decide on the Format

> Just because you can doesn't mean that you should.

Good things often don't come out of desire, but necessity.
GIF is cool because tis portable, but plain text is even more portable.
Multimedia weigh hundreds of kilobytes each, so they better best convey
whatever information they're meant to communicate.  Don't replace
the audio with a subtitle just so it can be an animated image.
Don't loop anything longer than a few seconds.

There is an old saying: *if tis doing fine being a video, let it be a video*.
Videos don't need each frame to be perfect, and thus all the following steps
can be done in a single ffmpeg command.  Work smart, even just for shitposting.

## Extract Frames

Open the source video in [mpv], seek then spam `s.` repeatedly.
That's all, y waste time write lot word wen few word do trick?

Aight, maybe there's a bit more to it.  Operating on the level of frames
will allow you to skip redundant ones in case of misencoded sources
or duplicate and reverse a subsequence for a closer-to-perfect loop,
but really, there's not much to talk about.

## Crop and Resize

Ripping a GIF from a video is taking a sequence of frames out of context.
Framing and some objects in the scene might not make sense in the target
animated image.  Some also like to export videos with giant black bars
just to fuck with us.  That's where cropping comes into play.  For measuring
I use [GIMP], which doesn't seem to be the right tool for the job,
so please let me know of anything lighter that has a ruler.

In addition, videos from social media (and space-efficient movies)
are heavily compressed and look pretty bad for their resolution.  Usually
I have to shrink them down to two third or a half of their original width
for them to look decently sharp.  When you have the geometry in mind,
summon the [image wizard][ImageMagick]:

```sh
crop="-crop ${w}x${h}+${dx}+${dy}"
resize="-resize ${width}x${height}"
parallel -i sh -c "convert $crop $resize"\
' {} $(basename {} .jpg).png' -- mpv-shot*.jpg
```

In case you don't have [moreutils]/[GNU parallel],
or if you are rocking a single-CPU machine, run:

```sh
mogrify $crop $resize -format png mpv-shot*.jpg
```

For resizing, image processing expert Nicolas Robidoux wrote
a long article on [resampling filters].  Although I can't spot
any distinction for this use case, it doesn't hurt to give it a read
and play around with different options.

![Pam stating that they are the same picture](/assets/same-picture.png)

## Combine

We are going to encode in best quality possible using [gifski].
The reason we converted from JPEG to PNG earlier is that our precious encoder
refuses to touch any other *image* format, and that mpv take screenshots
in JPEG by default (you can [configure][mpv screenshot] it to write in
lossless format but in my experience, the source videos are often too heavily
compressed for it to make any difference).  Anyhow, invoking gifski
is rather straightforward:

```sh
gifski -r $fps -Q 100 -o $name.gif mpv-shot*.png
```

Note that it optionally takes width and height as an argument
and yield better quality than with pre-shrunken images,
but at the cost of a significantly larger file size.  Choose wisely.

[inefficient]: https://telegram.org/blog/gif-revolution
[hyper]: https://nixnet.social/notice/A8VniqEBKfJvMc2dTE
[milos]: https://nixnet.social/notice/A9gMc47yxgoTNDIa7U
[grenade]: https://fe.disroot.org/notice/ANK2GqGxIdcDGBRAFU
[tron]: https://nixnet.social/notice/AOhGjOUwKJmiEFNLkG
[potato]: https://fe.disroot.org/notice/APhUh2H8radlKKIZGa
[]: https://fe.disroot.org/notice/APhUh2H8radlKKIZGa
[nf]: https://larkspur.one/notice/ATe4i9UvhxjiFvXprs
[role model]: https://www.youtube.com/watch?v=TVMK2gQig4A
[mpv]: https://mpv.io
[GIMP]: https://www.gimp.org
[ImageMagick]: https://imagemagick.org
[moreutils]: https://joeyh.name/code/moreutils
[GNU parallel]: https://www.gnu.org/software/parallel
[resampling filters]: https://imagemagick.org/Usage/filter/nicolas
[gifski]: https://gif.ski
[mpv screenshot]: https://mpv.io/manual/master/#screenshot