Hi, let's see if I am able to explain what I'm try to do in few words.
I have a series of small static images that I use in a forum signature, one of these images is an APNG of a cat walking.
I would like this unique image to move from the left to the right, and reappear to the right in a infinite loop.
I have already asked if it was possible to use some bbcode such as [marqueeleft] and [table],
but it seems it's quite complicated or not possible to set different table columns sizes.
So I decided to "cheat" trying to create a banner with this cat
https://i.postimg.cc/Qtpn2zNk/black-cat-walks-64.png
moving from the right to the left.
As I cannot find a simple way to do that, I thought I could maybe use some Avisynth commands in order to:
given an APNG, create a video banner where the image slowly scrolls, appearing from the right and disappearing on the left,
so then I can easily convert the video back to an APNG, having the image lenght that I want,
something like 500*64px or so, with the cat that moves in a loop.
where do I start from?
+ Reply to Thread
Results 1 to 22 of 22
-
Last edited by maudit; 26th Nov 2022 at 06:01.
-
Here's a basic example.
Code:function catwalk(clip background, clip cat, int xpos, int ypos) { xpos = xpos % (background.width + cat.width) - cat.width Overlay(background, cat, xpos, ypos, mask=cat.ShowAlpha()) } cat = LWlibavVideoSource("black-cat-walks-64.png").FlipHorizontal() # png with alpha channel, 88x64, 322 frames cat = cat.RGBADjust(r=0, g=0, b=0) cat = cat+cat+cat+cat+cat # make cat animation 5x longer background = ColorBars(width=640, height=480).Trim(0,1455) Animate(0, 1455, "catwalk", background,cat,0,259, background,cat,1456,259)
-
that's pretty nice, I really barely understand how all the commands are working, but thank you very much.
it's cool that I can decide the cat direction with ".FlipHorizontal()", maybe I could do a moonwalking cat.
now please, just a few fixes..
- the background must be white - idk maybe using "BlankClip()" instead of "ColorBars"?
- the resolution must be "A_NUMBER_THAT_I_CAN_DECIDE x 64"
- the length of the animation is doubled, I mean the cat passes 2 times, why?
why the trim is at 1455? can be fixed to exact one pass only? .Trim(0,727) is correct?Last edited by maudit; 26th Nov 2022 at 10:01.
-
Here's a simple mod to move the cat from left to right:
Code:function catwalk(clip background, clip cat, int xpos, int ypos) { xpos = xpos % (background.width + cat.width) - cat.width Overlay(background, cat, xpos, ypos, mask=cat.ShowAlpha()) } cat = LWlibavVideoSource("black-cat-walks-64.png").FlipHorizontal() # png with alpha channel, 88x64, 322 frames cat = cat.RGBADjust(r=0, g=0, b=0) cat = cat+cat+cat+cat+cat # make cat animation 5x longer background = ColorBars(width=640, height=480).Trim(0,1455) background = FlipHorizontal(background) Animate(0, 1455, "catwalk", background,cat,0,259, background,cat,1456,259) FlipHorizontal()
-
The background of what must be white? The background image? Instead of ColorBars() use BlankClip(color=color_white).
The resolution of the background must be N*64? N is the width:height of the overlay? Just some random numbers?
Code:background = BlankClip(width=cat.width*64, cat.height*64, color=color_white)
Code:background = BlankClip(width=10*64, 8*64, color=color_white)
http://avisynth.nl/index.php/Animate
Yes, you can trim to frame 727 to get only one pass. I wanted to show that the cat would automatically wrap around in longer videos because you asked for that -- "I would like this unique image to move from the left to the right, and reappear to the right in a infinite loop." You must extend the cat animation to be as long or longer than the background video if you want it to cover the entire length of the background video.Last edited by jagabo; 26th Nov 2022 at 10:35.
-
yes the background image, sorry I meant it must be Transparent, but if not possible, I'll remove the white color later.
white is ok, BlankClip(color=color_white) is ok.
the final resolution must be N(width)*64(same as the Apng height)
I don't know how to write the script. -
So you're looking to create a new big overlay (where the cat moves around) from the old small overlay? Not just overlay the PNG sequence onto a source video? I was showing how to do the latter.
-
I think it suppose to be a website banner, image that can loaded as some signature on a website. So just wide transparent PNG of walking cat.
But then he needs to provide actual width. -
[Attachment 67859 - Click to enlarge]This is a banner of a black cat walking with white background, cat appears from the left, just off screen and clip ends when it just walks off screen on the right,
you can select width of that banner choosing CLIP_MULTIPLE integer:
PHP Code:#python script
import vapoursynth as vs
from vapoursynth import core
import havsfunc
cat, alpha = core.ffms2.Source(r"C:\....your full path here....\black-cat-walks-64.png", alpha=True)
CLIP_MULTIPLE = 5 #sets aproximate banner width
START_POS = -cat.width #to start to walk just from off screen, cannot be less than:-cat.width
margins = 8 * 2* CLIP_MULTIPLE #cat has 8pixels margin from the frame
cat = cat.std.FlipHorizontal()
alpha = alpha.std.FlipHorizontal()
canvas = cat.std.BlankClip(width=CLIP_MULTIPLE*cat.width-margins,
color = (255,255,255),
length=CLIP_MULTIPLE*cat.width-margins-START_POS)
#making sure, length is longer that canvas length (length in these scripts is number of frames, not clip width)
cat = cat*3
alpha = alpha*3
banner = canvas.std.FrameEval(lambda n: havsfunc.Overlay(canvas, cat, x=max(-cat.width+1, n+START_POS), y=0, mask=alpha))
banner.set_output()
Alpha might be treated differently in ffms2 source plugin, in latest versions and latest vapoursynth versions, putting alpha into properties instead as a clip. If you'd have problem I'd fix that for latest version.Last edited by _Al_; 26th Nov 2022 at 21:46.
-
[Attachment 67869 - Click to enlarge]
choosing CLIP_MULTIPLE integer (in this example it is 10) for approximate clip width where script rounds it up to strictly mod 64, multiples of 64,
and again cat always appears on the left from off screen and just disappears on the right:
PHP Code:#python3
import vapoursynth as vs
from vapoursynth import core
import havsfunc
import functools
cat, alpha = core.ffms2.Source(r"C:\... path ...\black-cat-walks-64.png", alpha=True)
CLIP_MULTIPLE = 10 #sets aproximate banner length
START_POS = -cat.width #to start to walk just from off screen
margins = 8 * 2* CLIP_MULTIPLE #cat has 8pixels margin from the frame
width = CLIP_MULTIPLE*cat.width-margins
width = width + (64-width%64) #width is mod 64, rounded up
canvas = cat.std.BlankClip(width=width, color=(255,255,255), length=width-START_POS)
#making sure, number of frames for cat is more than canvas
mul = (canvas.num_frames//cat.num_frames) + 1
cat = cat.std.FlipHorizontal() * mul
alpha = alpha.std.FlipHorizontal() * mul
banner = canvas.std.FrameEval(lambda n: havsfunc.Overlay(canvas, cat, x=max(-cat.width+1, n+START_POS), y=0, mask=alpha))
banner.set_output()
Last edited by _Al_; 27th Nov 2022 at 01:04.
-
yes, thanks, that's what I'm trying to achieve. a cat walking in a forum signature.
A transparent APNG walking cat as a layer on a transparent background. (if not possible to get transparent background, white is ok too.)
The background must be 64px height and variable length.
the 2 previous examples are perfect except for the background color, can be set as transparent?
and by the way, all those Vapoursynth scripts, can be please converted/translated in a way that they works with Avisynth?Last edited by maudit; 27th Nov 2022 at 06:34.
-
Here is a rough template script modified from jagabo and _Al_ . It can probably be cleaned up a bit
The variables are up top, you can adjust the width but you have to adjust the framecount for a given width to make the motion more correct (other wise there will be more or less foot sliding) . The trim_ends are to reduce the transparent frames at the start and end of the animation, you might have to adjust it a bit
Code:bg_width = 480 total_frames = 500 trim_ends = 9 lwlibavvideoSource("black-cat-walks-64.png") fliphorizontal() loop(10) a=last a = a.trim(0, total_frames-1) b=blankclip(a, width=bg_width, color=color_white) bb=blankclip(a, width=bg_width) xpos_final=bg_width xpos_start=0-a.width rgb=Animate(0,a.framecount, "catwalk", b, a, xpos_start, b,a, xpos_final) alpha=Animate(0,a.framecount, "catwalka", bb, a, xpos_start, b,a, xpos_final) #as RGB CombinePlanes(RGB.extractr,RGB.extractg,RGB.extractb, alpha.extractr, planes="RGBA", source_planes="YYYY", sample_clip=b.converttoplanarrgba) #showframenumber() trim(trim_ends-1, last.framecount-trim_ends-1) function catwalk(clip background, clip fg, int xpos) { xpos = xpos Overlay(background, fg, xpos, mask=fg.ShowAlpha()) } function catwalka(clip background, clip fg, int xpos) { xpos = xpos Overlay(background, fg.showalpha, xpos) }
It's a cat race
ffmpeg -i script.avs -plays 0 -c:v apng apng.png
1.31MB
ffmpeg -i script.avs -loop 0 -c:v libwebp_anim -lossless 1 webp.webp
899KB
Pretty easy to do in a video editor too. Avisynth would not be most people's first choice to animate images -
Here's a simple method to generate the video with alpha channel:
Code:function CatPan(clip cat, int width, int height, int xpos, int ypos) { AddBorders(cat, width, height, width, height) Crop(width-xpos, height-ypos, width, height) } cat = LWlibavVideoSource("black-cat-walks-64.png") # png with alpha channel, 88x64, 322 frames cat = cat.RGBADjust(r=0, g=0, b=0) cat = cat+cat+cat # make cat animation 3x longer to make sure there is enough to walk entirely across the frame cat = cat.FlipHorizontal() FRAMEWIDTH = 640 # desired frame width FRAMEHEIGHT = 64 # desired frame height Animate(0, FRAMEWIDTH+cat.width, "catpan", \ cat, FRAMEWIDTH, FRAMEHEIGHT, -cat.width, 0,\ cat, FRAMEWIDTH, FRAMEHEIGHT, FRAMEWIDTH, 0) Trim(0, FRAMEWIDTH+cat.width) FlipHorizontal() AssumeFPS(24) # set whatever frame rate you want # # the video is all black at this point, but has an alpha channel, ie a black cat will be overlaid where the alpha channel indicates # # to see the alpha channel as a white cat on a black background: # ShowAlpha() # # or overlay cat onto a background video (all green here): # background = BlankClip(width=FRAMEWIDTH, height=FRAMEHEIGHT, color=color_green, length=FRAMEWIDTH+cat.width) # Overlay(background, last, mask=ShowAlpha()) # # or export an ARGB video or PNG sequence from an editor #
Sample attached with cat overlaid onto a green background.Last edited by jagabo; 27th Nov 2022 at 19:11.
-
thanks all of you guys, much appreciated.
that's awesome.. I'm gonna try to use them..
"cat race" lol.. -
How would I get alpha out of vapoursynth script to ffmpeg? Question perhaps for poisondeathray.
I have script outputting both:
Code:import vapoursynth as vs from vapoursynth import core import havsfunc cat, alpha = core.ffms2.Source(r"D:\downloads\black-cat-walks-64.png", alpha=True) CLIP_MULTIPLE = 10 #sets aproximate banner length START_POS = -cat.width+1 #to start to walk just from off screen margins = 8 * 2* CLIP_MULTIPLE #cat has 8pixels margin from the frame width = CLIP_MULTIPLE*cat.width-margins width = width + (64-width%64) #width is mod 64, rounded up canvas_cat = cat.std.BlankClip(width=width, color=(255,255,255), length=width-START_POS) canvas_alpha = canvas_cat.std.BlankClip(color=0, format=vs.GRAY8) #default is all transparent (black) #making sure, number of frames is more than canvas mul = (canvas_cat.num_frames//cat.num_frames) + 1 cat = cat .std.FlipHorizontal() * mul alpha = alpha.std.FlipHorizontal() * mul def get_x(n): #overlay cannot be fully outside of canvas return min(max(-cat.width+1, n+START_POS),canvas_cat.width-1) walking_cat = canvas_cat .std.FrameEval(lambda n: havsfunc.Overlay(canvas_cat, cat, x=get_x(n), y=0, mask=alpha)) walking_alpha = canvas_alpha.std.FrameEval(lambda n: havsfunc.Overlay(canvas_alpha, alpha, x=get_x(n), y=0, mask=alpha)) walking_cat.set_output() walking_alpha.set_output(1) if __name__ == '__main__': import view view.Preview([walking_cat, walking_alpha])
Last edited by _Al_; 28th Nov 2022 at 13:03.
-
Just to clarify latest alpha loading for Vapoursynth if anyone tests this, I have old setup for Vapoursynth but latest portable R60 and latest lsmash (HolyWu/Akarin dll) perhaps would load alpha like this:
Code:cat = core.lsmas.LWLibavSource("black-cat-walks-64.png") if isinstance(cat, (tuple,list)): cat = cat[0] alpha= cat[1] elif '_Alpha' in cat.get_frame(0).props: alpha = cat.std.PropToClip(prop='_Alpha')
-
Yes, for VPY R57+ versions, you need to use PropToClip . I like the old way better .
For RGBA and vspipe use rawvideo, and ffmpeg use -pix_fmt gbrap
Code:. . alpha = core.std.PropToClip(clip) clip.set_output(alpha=alpha)
Code:vspipe script.vpy - | ffmpeg -f rawvideo -s <width>x<height> -pix_fmt gbrap -r <framerate> -i - ...
-
thanks!
walking_cat.py with CLIP_MULTIPLE = 10:
Code:import vapoursynth as vs from vapoursynth import core import havsfunc cat, alpha = core.ffms2.Source(r"black-cat-walks-64.png", alpha=True) CLIP_MULTIPLE = 10 #sets aproximate banner length START_POS = -cat.width+1 #to start to walk just from off screen margins = 8 * 2* CLIP_MULTIPLE #cat has 8pixels margin from the frame width = CLIP_MULTIPLE*cat.width-margins width = width + (64-width%64) #width is mod 64, rounded up canvas_cat = cat.std.BlankClip(width=width, color=(255,255,255), length=width-START_POS) canvas_alpha = canvas_cat.std.BlankClip(color=0, format=vs.GRAY8) #default is all not transparent (black) #making sure, number of frames is more than canvas mul = (canvas_cat.num_frames//cat.num_frames) + 1 cat = cat .std.FlipHorizontal() * mul alpha = alpha.std.FlipHorizontal() * mul def get_x(n): #overlay cannot be fully outside of canvas return min(max(-cat.width+1, n+START_POS),canvas_cat.width-1) walking_cat = canvas_cat .std.FrameEval(lambda n: havsfunc.Overlay(canvas_cat, cat, x=get_x(n), y=0, mask=alpha)) walking_alpha = canvas_alpha.std.FrameEval(lambda n: havsfunc.Overlay(canvas_alpha, alpha, x=get_x(n), y=0, mask=alpha)) walking_cat.set_output(alpha=walking_alpha)
Code:import vapoursynth as vs from vapoursynth import core from subprocess import Popen, PIPE VSPipe = r'C:\... some path ..\vspipe.exe' ffmpeg = r'D:\... some path ..\ffmpeg.exe' output = r'D:\... some path ..\walking_cat.webp' script_path = r'D:\... same path as encode.py ..\walking_cat.py' output_index = 0 vs.clear_outputs import walking_cat #Getting clip just for properties, this is for old API3, not 4. clip, alpha = vs.get_output(output_index) #output is a tuple in our case #encoding script output vspipe_cmd = [VSPipe, '--outputindex', f'{output_index}', script_path, '-'] ffmpeg_cmd = [ffmpeg, '-f', 'rawvideo', '-s', f'{clip.width}x{clip.height}', '-pix_fmt', 'gbrap', '-r', f'{clip.fps.numerator/clip.fps.denominator}', '-i', '-', '-loop', '0', '-c:v', 'libwebp_anim', '-lossless', '1', output ] print(vspipe_cmd) print(ffmpeg_cmd) print('encoding ...') p1 = Popen(vspipe_cmd, stdout=PIPE, stderr=PIPE) p2 = Popen(ffmpeg_cmd, stdin=p1.stdout, stdout=PIPE, stderr=PIPE) p1.stdout.close() p2.communicate() print('done')
Last edited by _Al_; 28th Nov 2022 at 21:13.
-
But, he might show up with this cat!
Code:import vapoursynth as vs from vapoursynth import core import havsfunc CANVAS_WIDTH = 768 SPEED = 13 #speed over canvas, 1 is normal, but movement would be slow #gif has no alpha, just white background, so alpha is made cat = core.ffms2.Source(r"running_lion.gif") cat = cat.std.CropAbs(width=956, height=574, left=63, top=89) cat = cat.resize.Bicubic(width=int(cat.width*128/cat.height), height=128) alpha = cat.std.ShufflePlanes(planes=[0], colorfamily=vs.GRAY) alpha = alpha.std.Invert().std.Levels(max_in=235, max_out=255) START_POS = -cat.width+1 #to start to walk just from off screen canvas_cat = cat.std.BlankClip(width=CANVAS_WIDTH, color=(255,255,255), length=CANVAS_WIDTH-START_POS) canvas_alpha = canvas_cat.std.BlankClip(color=0, format=vs.GRAY8) #default is all not transparent (black) mul = (canvas_cat.num_frames//cat.num_frames) + 1 def one_run(cat, alpha): #making sure, number of frames is more than canvas cat = cat * mul alpha = alpha * mul def get_x(n): #overlay cannot be fully outside of canvas return min(max(-cat.width+1, n+START_POS),canvas_cat.width-1) walking_cat = canvas_cat .std.FrameEval(lambda n: havsfunc.Overlay(canvas_cat, cat, x=get_x(n*SPEED), y=0, mask=alpha)) walking_alpha = canvas_alpha.std.FrameEval(lambda n: havsfunc.Overlay(canvas_alpha, alpha, x=get_x(n*SPEED), y=0, mask=alpha)) end_trim = int(walking_cat.num_frames/SPEED) return walking_cat[0:end_trim], walking_alpha[0:end_trim] cat1, alpha1 = one_run(cat, alpha) cat = cat.std.FlipHorizontal() alpha = alpha.std.FlipHorizontal() cat2, alpha2 = one_run(cat, alpha) cat = cat1.std.Reverse()+cat2 alpha = alpha1.std.Reverse()+alpha2 cat.set_output(alpha=alpha)
image downloaded from: xxxxx://static.wixstatic.com/media/df67ef_1bf2d545aa57420398b9471c02fee3e8.gif
xxxxx=httpsLast edited by _Al_; 29th Nov 2022 at 16:49.
Similar Threads
-
Long exposure (add the difference forever) effect virtualdub or avisynth?
By zikmen in forum EditingReplies: 38Last Post: 18th Dec 2021, 08:05 -
Moving the entire video image up by 2 rows of pixels
By killerteengohan in forum RestorationReplies: 5Last Post: 28th Mar 2021, 23:55 -
It's possible to create a similar effect with avisynth?
By pokoloko in forum Newbie / General discussionsReplies: 7Last Post: 15th Jan 2021, 16:58 -
VirtualDub/AVISynth VHS Effect Script Error
By ElmoRocks05 in forum Video ConversionReplies: 49Last Post: 25th Jun 2020, 16:53 -
How to overlay a moving persons face with a 2D image and have it stay on.
By Lars Agerbęk with ę in forum EditingReplies: 3Last Post: 20th Dec 2019, 06:21