1

I have two gifs: aura.gif which is a 7 frames animation, and character.gif which is a 1 frame image. When I overlay one on top of the other as shown below, I get a 7 frames animated image but the character in character.gif only appears in the first frame.

How can I duplicate character 7 times so that when I overlay it over the aura the character shows in all 7 frames?

I cannot make character.gif animated from the start.

require 'vips'

character = File.open("character_no_animation.gif").read
character_b = Vips::Image.new_from_buffer(character, "", access: 'sequential', n: -1)

aura = File.open("aura.gif").read
aura_b = Vips::Image.new_from_buffer(aura, "", access: 'sequential', n: -1)

aura_b.composite(character_b, "over", x: 0, y: 0).gifsave("composite.gif")

Juan Alonso
  • 2,125
  • 2
  • 15
  • 16

2 Answers2

2

Cross-posted here:

https://github.com/libvips/ruby-vips/discussions/353

Which suggests:

require 'vips'

character = Vips::Image.new_from_file(ARGV[0])
aura = Vips::Image.new_from_file(ARGV[1], access: 'sequential')

character = character
    .replicate(1, aura.get("n-pages"))
aura
    .composite(character, "over")
    .write_to_file(ARGV[2])

That should be quicker since it's only one composite operation, not 7 on top of each other.

jcupitt
  • 10,213
  • 2
  • 23
  • 39
  • Much cleaner, thanks! When using `webp` I had to read the animated file, aura, with `access: 'sequential', n: -1` instead of just `access: 'sequential'`. Otherwise it works flawlessly. – Juan Alonso Dec 17 '22 at 20:23
0

I realized an animated image in Vips is loaded as an image with height * num_frames, so I ended up with this code which does what I need:

require 'vips'

character = File.open("character.gif").read
character_b = Vips::Image.new_from_buffer(character, "")

aura = File.open("aura.gif").read
aura_b = Vips::Image.new_from_buffer(aura, "", access: 'sequential', n: -1)

page_h = aura_b.get("height") / aura_b.get("n-pages")
aura_b.get("n-pages").times.each do |i|
  aura_b = aura_b.composite(character_b, "over", x: 0, y: page_h * i)
end

aura_b.gifsave("composite.gif")
Juan Alonso
  • 2,125
  • 2
  • 15
  • 16