Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How to overlay and repeat non-animated image over an animated one? #353

Answered by jcupitt
slnc asked this question in Q&A
Discussion options

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 make character.gif "appear" in all frames of aura.gif when I overlay both images?

This is the code I'm currently using:

require 'vips'
character = File.open("character.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).webpsave("composite.gif")

Thanks

You must be logged in to vote

Hi @slnc,

That'll work, but it'll be pretty slow since every pixel will need to pass through a stack of n_pages composite operations. A quicker solution would be to copy the character n_pages times vertically, then do a single composite for the whole animation.

replicate tiles images:

https://www.rubydoc.info/gems/ruby-vips/Vips/Image#replicate-instance_method

It's extremely quick (it just copies pointers), so you can use it instead of any kind of loop over the X and Y dimensions.

Something like:

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
 

Replies: 3 comments 4 replies

Comment options

After digging around a bit more I realized that Vips models animated images as a huge image so I ended up with this code which does what I need:

require 'vips'
character = File.open("character.webp").read
character_b = Vips::Image.new_from_buffer(character, "")
aura = File.open("aura.webp").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.webpsave("composite.webp")
You must be logged in to vote
0 replies
Comment options

Hi @slnc,

That'll work, but it'll be pretty slow since every pixel will need to pass through a stack of n_pages composite operations. A quicker solution would be to copy the character n_pages times vertically, then do a single composite for the whole animation.

replicate tiles images:

https://www.rubydoc.info/gems/ruby-vips/Vips/Image#replicate-instance_method

It's extremely quick (it just copies pointers), so you can use it instead of any kind of loop over the X and Y dimensions.

Something like:

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])

Then:

$ ./x.rb ~/pics/character.gif ~/pics/aura.gif[n=-1] x.gif

To make:

x

You must be logged in to vote
1 reply
Comment options

Thanks a lot John!

Answer selected by slnc
Comment options

Argh! Please don't cross post questions. It makes extra unnecessary work for volunteer maintainers.

You must be logged in to vote
3 replies
Comment options

I'm sorry, I checked activity on both SO for tag "vips" and on this forum before posting. I posted on both places because I got the impression that neither had a lot of activity. I realize now that SO has quite a bit of activity and that my assumption that if I got an answer on both places it would be better because a question and a solution would appear on two places instead of one.

Perhaps consider making this request (to not cross-post) a bit more visible with maybe a "How to get help" section and a message like "If you need help go here or here but don't cross post" either on https://www.libvips.org/ or https://github.com/libvips/libvips? I easily spent 1h browsing those two sites but if that section exists, I missed it. Just a suggestion to help other people who might be tempted to do like I did. :-)

Again, thank you for your help John. 🙏

Comment options

It's a general rule with all active open source projects: ask once, and only ask around if you don't get a reply. libvips is an evenings and weekends thing, and it'd obviously be much more fun to work on adding something new than answering the same question several times.

Comment options

I understand, I will follow your directions next time.

Thanks again for your help, the code you helped me with is already in production. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants

AltStyle によって変換されたページ (->オリジナル) /