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")
CodePudding user response:
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")
CodePudding user response:
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.