|
| 1 | +--- |
| 2 | +title: "How to make transparent GIFs easier shareable by adding a checkerboard background" |
| 3 | +date: 2024-10-15 |
| 4 | +tags: |
| 5 | +- imagemagick |
| 6 | +- gifsicle |
| 7 | +- bash |
| 8 | +- aseprite |
| 9 | +--- |
| 10 | + |
| 11 | +I'm currently taking part in the ["#hARToween" daily art challenge](https://social.horrorhub.club/@stina_marie/113220760493893634), as I want to |
| 12 | +work on my pixelart skills and drawing a 128x128px pixel drawing each day[^1] for a month seemed |
| 13 | +like a good idea. You can follow my posts [in this thread](https://chaos.social/@foosel/113233763230193057). |
| 14 | + |
| 15 | +I'm using [Aseprite](https://aseprite.org/), and recently came across [the "record for aseprite" script for it](https://sprngr.itch.io/aseprite-record) |
| 16 | +that allows taking regular snapshots of what I'm currently drawing so a timelapse can be created from |
| 17 | +that. And that works nicely, but I had to realize that the timelapse would come with transparency until |
| 18 | +I came to the background during my drawing, which looked really weird when sharing the resulting GIF. |
| 19 | + |
| 20 | +So I looked into adding the usual transparency checkerboard background to the GIF with a quick script, |
| 21 | +and of course, [ImageMagick](https://imagemagick.org/) once more to the rescue. Alas, the resulting GIF was quite large and ImageMagick's |
| 22 | +optimization options caused glitches in the GIF. So I looked for another option to optimize the GIF and |
| 23 | +came across [gifsicle](https://www.lcdf.org/gifsicle/). |
| 24 | + |
| 25 | +The result is this bash script which will take a GIF and an optional background image to set, |
| 26 | +add the background (or a freshly generated checkerboard pattern of the right size) to the GIF, then compress |
| 27 | +the GIF: |
| 28 | + |
| 29 | +``` bash |
| 30 | +#!/bin/bash |
| 31 | + |
| 32 | +GIF=$1 |
| 33 | +BG=$2 |
| 34 | + |
| 35 | +BASE=$(basename "${GIF%.*}") |
| 36 | +OUTPUT="$BASE.bg.gif" |
| 37 | + |
| 38 | +if [ -f "$BG" ]; then |
| 39 | + echo "Adding background image $BG to all frames of $GIF..." |
| 40 | + magick "$GIF" -coalesce null: "$BG" -compose dstOver -layers composite "$OUTPUT" |
| 41 | +else |
| 42 | + size=$(gifsicle --sinfo "$GIF" | grep "logical screen" | xargs echo -n | cut -d" " -f 3) |
| 43 | + |
| 44 | + echo "Generating a $size checkerboard pattern and adding it as background to all frames of $GIF..." |
| 45 | + magick "$GIF" -coalesce null: \( -size $size tile:pattern:checkerboard \) -compose dstOver -layers composite "$OUTPUT" |
| 46 | +fi |
| 47 | + |
| 48 | +echo "Optimizing $OUTPUT..." |
| 49 | +gifsicle --batch -O3 --lossy=35 "$OUTPUT" |
| 50 | + |
| 51 | +echo "...done!" |
| 52 | +``` |
| 53 | + |
| 54 | +Example call: |
| 55 | + |
| 56 | +``` plain |
| 57 | +$ gif_bg 14.gif |
| 58 | +Generating a 256x256 checkerboard pattern and adding it as background to all frames of 14.gif... |
| 59 | +Optimizing 14.bg.gif... |
| 60 | +...done! |
| 61 | +``` |
| 62 | + |
| 63 | +I'm quite happy with the result: |
| 64 | + |
| 65 | +{{< toot "https://chaos.social/@foosel/113306303596486838" >}} |
| 66 | + |
| 67 | +[^1]: Well, almost, I was at MRMCD and then a bit under the weather after and thus missed some days that I'm now trying to catch up on again. |
0 commit comments