Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
|
|
Thread Tools | Search this Thread | Display Modes |
5th April 2020, 14:16 | #1 | Link | |
Registered User
Join Date: Dec 2017
Posts: 4
|
Append a still image respecting aspect ratio and possibly adding borders
I'm looking to append a still image to a video clip.
I found an old thread that deals with this issue. Unfortunately I'm facing distortion problems and can't adapt the script. Gavino mentioned at the time that this script should be improved... Quote:
Can someone show me the way because abstraction is not my strong point? (such scripts probably already exist) Code:
v=DirectShowSource("F:\Vidéos\Enfants\Minuscule\gay-minus.avi") pic="D:\pic\screenshot_395.png" t=10 #[time in sec] fc=Round(t*FrameRate(v)) #frame count #################################################### # Option Zoom d=20 # start zooming n = 50 # no of frames for still endzoom = 4.0 #################################################### ImageSource(pic).ConvertToRGB32() AssumeFPS(v).Loop().Trim(0,fc-1) #~ Animate(last, d, 119, "SimpleZoomBox", 1.0, 0, 0, endzoom, (endzoom * -0.10), (endzoom * 0.9)) # Option Zoom AudioDub(BlankClip(v, length=t)) fv=last # frozen vid vasr=float(v.Height)/float(v.Width) #video aspect ratio pasr=float(fv.Height)/float(fv.Width) #picture aspect ratio nW=INT(fv.Width*(pasr*vasr)) #new Width xx=(v.Width-nW) #sum of the lateral borders Spline36Resize(nW, v.Height).AddBorders(xx/2,0,xx/2,0) #~ ConvertToYV12() #~ v ++ last #joining both clips last #only for picture clip |
|
5th April 2020, 15:43 | #2 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,869
|
Ok so basically if I got it right you want to append images of different sizes by respecting the Aspect Ratio and therefore have them resized automatically without distortion but by adding borders instead?
Well, that seems a pretty good job for Frosty Border! |
5th April 2020, 16:19 | #3 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
May be of interest [ImageSplicer, Included in RT_Stats zip]:- https://forum.doom9.org/showthread.p...er#post1713501
Predecessor [PicVidShow]:- https://forum.doom9.org/showthread.p...43#post1604043 EDIT: This seems to be an update of PicVidShow. [remove GScript Wrapper for AVS+] Code:
# EDIT To Suit # https://forum.doom9.org/showthread.php?p=1604043#post1604043 VID = True # True == Video : False == Pics, see IN_FILES directories/wildcards IN_FILES = (VID) ? "D:\VID\*.AVI|MP*G" : "D:\Pics\*.BMP|JP*G|PNG" # Added '|' Pipe separator for multiple Wildcard in Extensions ONLY. AUTOCROP = True # Crop off black borders. SHOWBORDER = True # True Show replaced border in Red, else Black. (Test AUTOCROP) AUTOLEVEL_STRENGTH = 0.666 # AutoLevel Strength 0.0 -> 1.0 SHOWAUTOLEVEL = True # Right Hand Side Only AutoLeveled # FAR = 4.0/3.0 # Required Output Frame Aspect Ratio SzLimit = 1024 DEBUG = False # Debug # --------------------- BORDER = (SHOWBORDER) ? $FF0000: (VID) ? $101010 : $000000 # Color for replaced borders. SUBS = True # Subtitles on clips/images DEBUG_QBC = True # Debug QueryBorderCrop DEBUG_QLMM = True # Debug QueryLumaMinMax FPS = (VID) ? 30000.0/1001.0 : 1.0 # Whatever. OUT_FILE = "FILE.List" # Dont need to change really, just a name. #-------------------------------------------------------------------------------- GScript(""" picclip = 0 # dummy for now result=RT_WriteFileList(IN_FILES,OUT_FILE) # Create a listing file of Pic files Assert((result!=0), "No files found") FILELIST=RT_ReadTxtFromFile(OUT_FILE) # Get list of files FILES=RT_TxtQueryLines(FILELIST) # Query Number of lines in String ie number of files. if(DEBUG){RT_Debug("Found files = " + String(FILES))} # Prescan to ascertain max wid/hit of all files, also Autocrop & Auto Levels MAXH=0 MAXW=0 # init max wid and hit CROPCOORDS="" AUTOLEVELS="" AUTOLEVEL=(AUTOLEVEL_STRENGTH>0.0) # Adjust using Levels. For(i=0,FILES-1) { FN=RT_TxtGetLine(FILELIST,i) # Filename of avi file i if(DEBUG){RT_Debug(String(i)+") Getting File dimensions",FN)} if(VID) { k=DirectshowSource(FN) k=k.ConvertToYUY2().Trim(0,0) } else { k=ImageReader(FN,end=0).ConvertToRGB32() # With Bmap, some come up as RGB24 bit some RGB32. } OrgH=k.height OrgW=k.width if(DEBUG){RT_Debug ("Orig Width =",String(orgW),"Orig Height =",String(OrgH))} if (AUTOCROP) { QBC = k.QueryBorderCrop(samples=24,laced=VID,debug=(DEBUG&&DEBUG_QLMM)) QBC = RT_TxtGetLine(QBC,2) # CropMore CROPCOORDS=RT_TxtAddStr(CROPCOORDS,QBC) # Avisynth Bugfix, same as CROPCOORDS = CROPCOORDS + QBC + Chr(10) Eval(QBC) k=k.Crop(QBCropXM,QBCropYM,QBCropWM,QBCropHM) } if (AUTOLEVEL) { QLMM = k.QueryLumaMinMax(debug=(DEBUG&&DEBUG_QLMM)) Eval(QLMM) AUTOLEVELS=RT_TxtAddStr(AUTOLEVELS,QLMM) # Avisynth Bugfix, same as AUTOLEVELS = AUTOLEVELS + QLMM + Chr(10) } H=k.height W=k.width If(MAXH<H) {MAXH=H} If(MAXW<W) {MAXW=W} if(DEBUG){RT_Debug("MAX Width So Far =",String(MAXW),"MAX Height So Far =",String(MAXH))} if(DEBUG){RT_Debug(" ----------------------------- ")} # line separator } maxFAR = MAXW / MAXH if(FAR >= maxFAR) { canvasheight = (MAXH > SzLimit) ? SzLimit : MAXH canvasheight = ((canvasheight + 1) / 2) * 2 canvaswidth = Int((canvasheight * FAR + 2) / 4) * 4 } else { canvaswidth = (MAXW > SzLimit) ? SzLimit : MAXW canvaswidth = ((canvaswidth + 2) / 4) * 4 canvasheight = Int((canvaswidth * FAR + 1) / 2) * 2 } if(DEBUG){RT_Debug("SETTING CanvasWidth =",String(canvaswidth)," CanvasWeight =",String(canvasheight))} if(DEBUG){RT_Debug(" ----------------------------- ")} # line separator For(i=0,FILES-1) { FN=RT_TxtGetLine(FILELIST,i) # Filename of avi file i if(DEBUG){RT_Debug(string(i)+ ")","Processing File",FN)} if(VID) { k=DirectshowSource(FN).ConvertToYUY2().Trim(0,0) } else { k=ImageReader(FN,end=0).ConvertToRGB32() # With Bmap, RGB24 problems with addborders } OrgH=k.height OrgW=k.width if (AUTOLEVEL) { # We do AUTOLEVELS before crop, because of SHOWAUTOLEVEL QAT = RT_TxtGetLine(AUTOLEVELS,i) Eval(QAT) if(k.IsYUV()) { CSMin = 16 CSMax = 235 } else { CSMin = 0 CSMax = 255 } TMP_K=k ALMin = Int(CSMin - ((CSMin - QLMMMin) * AUTOLEVEL_STRENGTH) + 0.5) # Round Up ALMax = Int(CSMax - ((CSMax - QLMMMax) * AUTOLEVEL_STRENGTH)) # Round down k = k.Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # DONT USE Coring if(SHOWAUTOLEVEL) { tmpw=int((k.width/4)*2) Left = TMP_K.Crop(0,0,tmpw,-0) Right= k.Crop(tmpw,0,-0,-0) k=StackHorizontal(Left,Right) } } if (AUTOCROP) { QBC = RT_TxtGetLine(CROPCOORDS,i) Eval(QBC) k=k.Crop(QBCropXM,QBCropYM,QBCropWM,QBCropHM) } iWidth=k.Width() iHeight=k.Height() cFAR = float(canvaswidth) / canvasheight iFar = float(iWidth) / iHeight Left=0 Top=0 Right=0 Bot=0 if(iFAR >= cFAR) { oWid = canvaswidth oHit = (oWid*iHeight/iWidth/4)*4 Top = (canvasheight-oHit) / 2 Bot = canvasheight - oHit - Top } else { oHit = canvasheight oWid = (oHit*iWidth/iHeight/4)*4 Left = (canvaswidth-oWid) / 2 Right = canvaswidth - oWid - Left } RT_Debug("Resize","oWid="+String(oWid),"oHit="+String(oHit),"Left="+String(Left),"Top="+String(Top),"Rgt="+String(Right),"Bot="+String(Bot)) k = k.Spline36Resize(oWid,oHit).addborders(Left,Top,Right,Bot,BORDER).assumefps(fps) if(SUBS) { k=k.subtitle(String(i) + "/"+String(FILES-1) +" " + FN) k=k.subtitle("Orig width=" + string(orgW) +" " + "Orig height=" + string(orgH) +" FAR="+String(Float(orgW) /orgH, "%.2f"),20,20) if (AUTOCROP) {k=k.subtitle("Crop width=" + string(iWidth) +" " + "Crop height=" + string(iHeight) +" FAR="+String(Float(iWidth) /iHeight, "%.2f"),20,40) } else {k=k.subtitle("NO AUTOCROP",20,40)} k=k.subtitle("New width=" + string(oWid) +" " + "New height=" + string(oHit)+" FAR="+String(Float(oWid)/oHit,"%.2f"),20,60) k=k.subtitle("Out width=" + string(k.Width) +" " + "Out height=" + string(k.Height)+" FAR="+String(Float(k.Width)/k.Height,"%.2f"),20,80) if(AUTOLEVEL) { k=k.subtitle("Auto Levels(" + String(ALMin) + ",1.0," + String(ALMAx) + "," + String(CSMin) + "," + String(CSMax) + ")",20,100) k=k.subtitle("QLMMMin = " + String(QLMMMin) + " QLMMMax = " +String(QLMMMAx),20,120) k=k.subtitle("AUTOLEVEL @ " + String(AUTOLEVEL_STRENGTH*100.0,"%.0f") + "%",20,140) } else {k=k.subtitle("NO AUTOLEVEL",20,100)} } picclip = (IsClip(picclip)) ? picclip ++ k : k # Append to clip so far if(!VID){k=k.ConvertToRGB24()} if(DEBUG){RT_Debug(" ")} # line separator if(DEBUG){RT_Debug(" ----------------------------- ")} # line separator } """) PicClip Code:
import(".\ImageSplicer.avs") FN=".\*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF" SZLIMIT = -768 # Height=Abs(SZLIMIT) FAR = 4.0/3.0 AUTOCROP = TRUE STRENGTH = 0.66 SHOWAL = False SHOWBORD = False SUBS = False CROPTHRESH = -0.5 FPS = 1.0 WMOD = 4 HMOD = 4 DEBUG = TRUE IGNORE = 0.4 BORDCOL = $001144 # Added for goorawin ATM = 0.5 # Added, arg to QueryborderCrop myName="ImageSplice_Client_2: " IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript") Assert(IsAvsPlus || HasGScript,RT_String("%sNeed either GScript or AVS+",myName)) Anim = ImageSplicer(FN,SzLimit=SZLIMIT,Far=FAR,AutoCrop=AUTOCROP,AutoLevelStrength=STRENGTH,ShowAutoLevel=SHOWAL,ShowBorder=SHOWBORD, \ Subs=SUBS,CropThresh=CROPTHRESH,Fps=FPS,Wmod=WMOD,Hmod=HMOD,Debug=DEBUG,IGnore=IGNORE,BorderColor=BORDCOL,ATM=ATM) OUT_SecondsPerFrame = 5 # How long each frame is diplayed for OUT_FPS = 25.0 # Final Output FrameRate FADE_FRAMES = Int(OUT_FPS/2) T1 = Int(OUT_SecondsPerFrame*OUT_FPS) T2 = T1+FADE_FRAMES anim.AssumeFPS(1).ChangeFPS(T2) # repeat each frame for OUT_SecondsPerFrame + ~0.5 sec overlap Vid = Trim(FADE_FRAMES, -T1) # first chunk GS=""" for (f=T2, Framecount-T2, T2) { next = Trim(f, -T2) # next chunk, incl overlap vid = Dissolve(vid, next, FADE_FRAMES) } """ HasGScript ? GScript(GS) : Eval(GS) # Use GSCript if installed (loaded plugs override builtin) Return Vid.AssumeFPS(OUT_FPS) Code:
Import(".\ImageSplicer.avs") FN=".\*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF" SzLimit= -768 FAR=1.333 AutoCrop=True AutoLevelStrength=1.0 ShowBorder=True ShowAutoLevel = True Subs = True CropThresh = -0.5 FPS = 1.0 WMOD = 4 HMOD = 4 IGNORE = 0.4 ScanPerc = 49.0 Baffle = 4 Debug = True Debug_QBC = False Resizer = "Spline64resize(_W_,_H_)" # Change to eg "Spline36resize(_W_,_H_)" Matrix = 2 ATM = 0.5 TimeStart = RT_Timer() ImageSplicer(FN,SzLimit,FAR=FAR,AutoCrop=AutoCrop,AutoLevelStrength=AutoLevelStrength,ShowBorder=ShowBorder,ShowAutoLevel=ShowAutoLevel, \ Subs=Subs, CropThresh=CropThresh,Fps=FPS,Wmod=WMOD,Hmod=HMOD,Baffle=Baffle,ScanPerc=ScanPerc,Debug=Debug,Debug_QBC=Debug_QBC, \ Ignore=IGNORE,Resizer=Resizer,matrix=matrix,ATM=ATM) #ImageSplicer(FN,SzLimit=1024) TimeEnd = RT_Timer() SubTitle("TIME = "+String(TimeEnd-TimeStart,"%6.2f")+" secs",align=9,Y=0)
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 5th April 2020 at 16:30. |
5th April 2020, 20:14 | #5 | Link |
Registered User
Join Date: Dec 2017
Posts: 4
|
Thank you, three of you,
As you can see, this is my second post and I'm very beginner with avisynth. This post is also an exercise to learn more about avisynth and try to improve an existing script. So I think I should have refrained from mentioning the existence of an already existing script. FranceBB, I studied the FrostyBorder function but I don't think it's adapted to my needs : this function applies to a video while I'm trying to manipulate an image (then transformed it into a video). Add vertical or horizontal black borders so that the generated image is the same size as the video clip. You can even guess in my script that I want to zoom in this picture. The StainlessS proposal is even more complex for me; I clearly don't yet have the knowledge for it. Please be indulgent for my perhaps clumsy remarks. The script is almost working but I need your knowledge to make it really usable. Last edited by PerDeConf; 5th April 2020 at 20:18. |
6th April 2020, 08:18 | #6 | Link | ||
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,869
|
Quote:
Quote:
Alright, I've collected four randomly chosen pictures from the internet at different aspect ratios and resolutions: Image 1 - Margot Robbie Image Format : JPEG Width : 500 pixels Height : 500 pixels Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Compression mode : Lossy Stream size : 46.9 KiB (100%) ColorSpace_ICC : RGB Image 2 - Taylor Swift Image Format : JPEG Width : 1 778 pixels Height : 2 667 pixels Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Compression mode : Lossy Stream size : 983 KiB (100%) Image 3 - Elsa Hosk Image Format : JPEG Width : 800 pixels Height : 1 200 pixels Color space : YUV Chroma subsampling : 4:4:4 Bit depth : 8 bits Compression mode : Lossy Stream size : 294 KiB (100%) Image 4 - a cat Image Format : JPEG Width : 960 pixels Height : 640 pixels Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Compression mode : Lossy Stream size : 70.3 KiB (100%) Now, first of all let's index them within our script. What I'm gonna use is ImageSource. The reason is that it will allow me to easily specify the number of frames that can be used and I suggest it over FFImageSource also because if you have .png files then FFImageSource will NOT work as it only indexes JPEG files and we don't know whether it will ever support other kind of images or not. So, let's start: Code:
ImageSource("margot-robbie.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") As you can see, Margot ain't a picture anymore, it's now a video which lasts 1000 frames, has 25fps and is in 8bit RGB32. Now, we have three more images, but to append them they gotta be the same as our final stream has to be consistent which means they gotta be at the same resolution, color space, framerate and bit depth, so how do we do that? Well, let's suppose that our output is 848x480 at 25fps. We can use FrostyBorder to make it happen: Code:
ImageSource("margot-robbie.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") Converttoyv12() FrostyBorders(848,480, frosty=true) As you can see, we now have a perfectly valid 848x480 4:2:0 planar 8bit (yv12) 16:9 1.77FF stream. Let's do that with all the other images and then let's add them together, shall we? Code:
clip=ImageSource("taylor-swift.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") my_initial_width=clip.Width() my_initial_heigth=clip.Height() i_width = my_initial_width / 2 * 2 i_height = my_initial_heigth / 2 * 2 Spline64Resize(clip, i_width, i_height) Converttoyv12() FrostyBorders(848,480, frosty=true) Code:
ImageSource("elsa-hosk.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") Converttoyv12() FrostyBorders(848,480, frosty=true) and lastly our picture of a cat: Code:
ImageSource("cat.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") Converttoyv12() FrostyBorders(848,480, frosty=true) Ok, so now we're ready to append them together and get a 4000 frames 848x480, 25fps 4:2:0 planar 8bit video out of our images for our fictional actress/singer/model/animal advertising company doomed to fail xD like so: Code:
ImageSource("margot-robbie.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") Converttoyv12() FrostyBorders(848,480, frosty=true) img1=last clip=ImageSource("taylor-swift.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") my_initial_width=clip.Width() my_initial_heigth=clip.Height() i_width = my_initial_width / 2 * 2 i_height = my_initial_heigth / 2 * 2 Spline64Resize(clip, i_width, i_height) Converttoyv12() FrostyBorders(848,480, frosty=true) img2=last ImageSource("elsa-hosk.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") Converttoyv12() FrostyBorders(848,480, frosty=true) img3=last ImageSource("cat.jpg", start=0, end=1000, fps=25, pixel_type="RGB32") Converttoyv12() FrostyBorders(848,480, frosty=true) img4=last img1++img2++img3++img4 I hope this is clear enough to clarify your doubts. Now I really gotta "go" to work (where "go" means stop scrolling doom9, shut down Windows XP, boot into Windows 10 here at home, and actually train a flipping object/people/setting/speech recognition AI which is exactly what I've been doing for months ever since they re-assigned me from the encoding department and I'm sick of it... T_T) Last edited by FranceBB; 6th April 2020 at 08:25. |
||
7th April 2020, 19:39 | #7 | Link |
Registered User
Join Date: Dec 2017
Posts: 4
|
Thank you very much FranceBB for such a well-documented explanation.
Your post enlightened me on aspects of Avisynth that I had not assimilated well. It is now much clearer and I thank you for the explicit and very pleasant use of images, I confess. I took my time and with a little trial and error I managed to get the result I wanted. In the end I preferred to use Imageborders because by zooming in on the edge of the image, Frostyborders let a black border appear, too different from the nice effect I expected (see attachment). Finally, I want to thank raffriff42 for his simpleZoombox script that made my job so much easier and of course hello_hello for FrostyBorders. So here's what I came up with: Code:
v = dss2("(2020-04-07 09-00) L'heure des pros [CNEWS].ts", lavs="l3", lavd="l3", preroll=64) a = DirectShowSource("(2020-04-07 09-00) L'heure des pros [CNEWS].ts", video=False) AudioDub(v,a) trim (1458, 1899) LanczosResize(1280,720) v=last pic="D:\pic\screenshot_395.png" t=5 #[time in sec] fc=Round(t*FrameRate(v)) #frame count # Option Zoom endzoom = 2.0 ImageSource(pic, pixel_type="RGB32") Converttoyv12() ImageBorders(Width(v),height(v)) AssumeFPS(v).Loop().Trim(0,fc-1) ConvertToRGB32() Animate(last, \ 1, \ 119, \ "SimpleZoomBox", \ 1.0, 0, 0, \ endzoom, (endzoom * 0.10), (endzoom * 0.9)) AudioDub(BlankClip(v, length=t)) ConvertToYV12() v ++ last #joining both clips #~ last #only for picture clip |
Tags |
aspect ratio, avisynth, still image |
Thread Tools | Search this Thread |
Display Modes | |
|
|