Fill background in animated gif?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Fill background in animated gif?

Post by snibgo »

I'm not experienced at GIF animations, but the following works for me, v6.8.7 on Windows 7:

Code: Select all

D:\web\im>convert frames\*.png -set delay 1x24 -coalesce -trim -set dispose background -layers TrimBounds out.gif
The blue background shrinks against a background that is white on my viewers.
snibgo's IM pages: im.snibgo.com
Smoshy
Posts: 14
Joined: 2013-10-05T18:16:01-07:00
Authentication code: 6789

Re: Fill background in animated gif?

Post by Smoshy »

fmw42 wrote:I gave it my best try but was unsuccessful working around this.
Ah well. Thanks for taking the time to have a go!
Smoshy
Posts: 14
Joined: 2013-10-05T18:16:01-07:00
Authentication code: 6789

Re: Fill background in animated gif?

Post by Smoshy »

snibgo wrote:The blue background shrinks against a background that is white on my viewers.
That's the problem... I want the background to be the same blue.

Strangely, I can get this working if I choose red as the background, but when I change that to khaki (for testing) or this cadet grey, it fails again.

I am perplexed.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Fill background in animated gif?

Post by snibgo »

Ah, okay. How about:

Code: Select all

convert ^
  frames\*.png ^
  -set delay 1x24 ^
  -background #889db3 ^
  -gravity Center ^
  -trim +repage -extent 249x492 ^
  -coalesce ^
  -set dispose background ^
  -layers TrimBounds ^
  out.gif
snibgo's IM pages: im.snibgo.com
Smoshy
Posts: 14
Joined: 2013-10-05T18:16:01-07:00
Authentication code: 6789

Re: Fill background in animated gif?

Post by Smoshy »

Excellent! Thank you for this!

However, just to be awkward...

I have a whole stack of animations to make. Is there any way to avoid that -extent 249x492 and instead something like -extent (size of union of all frames in this animation). If not, I'll just have to hardcode that in.

(Edited to add
Also, I've just noticed : does repage re-center the image? The soldier's feet rise towards the middle as he kneels. I'd prefer to keep the ground at ground level - so the offsets of the individual frames would have to remain untouched.
)

(Edited again : Nope, that's the gravity. But some of the animations can't but put in the center or along the bottom edge. I don't think gravity is the answer here, I really need the original offets from the trim.)
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Fill background in animated gif?

Post by snibgo »

249x492 comes from this:

Code: Select all

convert ^
  frames\*.png ^
  -set delay 1x24 ^
  -background #889db3 ^
  -coalesce ^
  -trim +repage ^
  -set dispose background ^
  -layers TrimBounds ^
  -format "%%P%%O\n" -write info: ^
  dummy.gif
Note that here the "-trim +repage" comes after "-coalesce", not before. I don't know enough about GIF animations to explain this. Run this before the main command, pull out the dimensions with a script, and use that in the main command. You can probably remove some stuff from this dummy command.

You don't actually need to create dummy.gif, so it could be:

Code: Select all

convert ^
  frames\*.png ^
  -set delay 1x24 ^
  -background #889db3 ^
  -coalesce ^
  -trim +repage ^
  -set dispose background ^
  -layers TrimBounds ^
  -format "%%P%%O\n" info:
Or you could create dummy.gif, and use identify to get the dimension of just one frame:

Code: Select all

identify -format "%%P" dummy.gif[0]

"+repage" would put it top-left. I used "-gravity Center" to centre each one. You can omit either or both. In my experiments I couldn't figure out how to retain the ground level (ie keep his right foot stationary).
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Fill background in animated gif?

Post by fmw42 »

Snibgo, your -extent was what was missing from my approach. Brilliant. I tried adding a zero delay frame, but it kept getting trimmed away. I found that the animation size was slightly different on my Mac for some unknown reason when testing the original command.

So in unix, this works for me where I had measured the background color (blue) in rgb values.

convert \
frames/*.png \
-set delay 1x24 \
-background "rgb(136,157,179)" \
-gravity Center \
-trim +repage -extent 253x521 \
-coalesce \
-set dispose background \
-layers TrimBounds \
out.gif

or

convert \
-background "rgb(136,157,179)" \
-dispose background \
-delay 1x24 \

frames/*.png \
-gravity Center \
-trim +repage \
-extent 253x521 \
-coalesce \
-layers TrimBounds \
-layers optimize \
out.gif


settings such as -dispose and -delay should come before reading the input. however, you can use the -set option with them in order the put them after the input as you have them
Smoshy
Posts: 14
Joined: 2013-10-05T18:16:01-07:00
Authentication code: 6789

Re: Fill background in animated gif?

Post by Smoshy »

fmw42 your solution has the same problem as snibgo's - ground level doesn't stay constant.

In the end I hacked up some Java that took in the source frames, trimmed and aligned them, and wrote them out as png24 frames for imagemagick to convert to a gif or mng. I was going to quantize and build the gif myself, but there are too many ways to go wrong there.

I'd still be interested if this can be done in 1 line with imagemagick as opposed to 3k of Java, but I've acheived what I needed to do. Thank you both for your time.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Fill background in animated gif?

Post by fmw42 »

try either changing -gravity center to -gravity south or take out the -gravity center.
Smoshy
Posts: 14
Joined: 2013-10-05T18:16:01-07:00
Authentication code: 6789

Re: Fill background in animated gif?

Post by Smoshy »

South means the bottom pixel of the animation stays at the bottom - but halfway through, his knee becomes lower than his feet, so his right foot starts floating. Without any gravity, his helmet stays constant and his feet float. I don't think it can be done without the original trim offsets - +repage is destroying that information.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Fill background in animated gif?

Post by snibgo »

Keeping his right foot steady:

Code: Select all

convert ^
  frames\*.png ^
  -trim -layers TrimBounds ^
  outD_%%03d.png

mogrify -background #889db3 -layers flatten outD_*.png

convert ^
  outD_*.png ^
  -set delay 1x24 ^
  outD3.gif
Perhaps the three commands could be combined.

The hardcoded colour #889db3 could be picked from, say, the top-left corner of an image.
snibgo's IM pages: im.snibgo.com
Smoshy
Posts: 14
Joined: 2013-10-05T18:16:01-07:00
Authentication code: 6789

Re: Fill background in animated gif?

Post by Smoshy »

Ah, now that would work. I didn't consider a middle mogrify, and that solution is so unintuitive I'd never have stumbled upon it.

Problem thoroughly solved. Thanks again.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Fill background in animated gif?

Post by snibgo »

I was trying to figure out how to use the virtual canvas data that comes not just from "-trim" but also "-layers TrimBounds". "-extent" and "-compose" both ignore it. We could do some scripting that would extract the canvas data and write to "-geometry". Then something clicked, and I remembered that "-layers flatten" uses canvas data. But we can't do this to the 24 images or they will flatten into a single image. We need to flatten each individual image. I couldn't see how to do that in a single convert, so the solution was to write each frame and "-layers flatten" each one.

It's a slightly horrible solution, with all those reads and writes. Using miff instead of png will be slightly faster.

Code: Select all

convert ^
  frames\*.png ^
  -trim -layers TrimBounds ^
  outD_%%03d.miff

mogrify -background #889db3 -layers flatten outD_*.miff

convert ^
  outD_*.miff ^
  -set delay 1x24 ^
  outD3.gif
Piping might also be used.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Fill background in animated gif?

Post by fmw42 »

I also tried to figure out how to do this without the mogrify. But could not come up with a solution. Perhaps Anthony might know how.
Post Reply