Log in

View Full Version : Using for loop with imagewriter


Georgiana
1st May 2020, 15:20
Is there any chance to use a for loop and inside this loop to have executed a series of imagewriters? One at each step of the loop, in order to write some frames of a clip? I have already tried:

for (i=0,3,1)
{
imagewriter (clip,"path",start=i,end=i,type="jpg")
}

But it seems that ONLY for the last value of i, the imagewriter is executed. How could I tell the imagewriter to be executed for my specific number of steps, not only for the last one? Thank you for any advice!

Gavino
1st May 2020, 20:26
The reason this doesn't work is that ImageWriter() only produces output when frames are requested from the filter, and for this to happen the filter must be in the filter graph contributing to the final result of the script.
In your script, only the last loop iteration is used in the result of the script so it's the only one that actually does any writing.

But if I understand what you are trying to do, you don't need a loop here.
Just:
ImageWriter(clip,"path",start=0,end=3,type="jpg")

StainlessS
1st May 2020, 21:02
Damn that Gavino, stays aways for years at a time and then jumps in to spoil my fun.

Anyway, pretending that above did not happen.

script 1 [EDIT: play file at least past last write frame]

/*

ImageWriter(clip, string "file", int "start", int "end", string "type", bool "info")

*/

Colorbars().Trim(0,-200) # 200 frames
ShowFrameNumber

FILE="D:\IMWR\MyFile_"
START=100
END=103
TYPE = "jpeg"
INFO=False
ImageWriter(File=FILE,Start=START,end=END,type=TYPE,info=INFO) # Output MyFile_000100.jpeg -> MyFile_000103.jpeg
Return last


script 2 [EDIT: play complete 4 frame clip]

Colorbars().Trim(0,-200) # 200 frames
ShowFrameNumber

Trim(100,-4) # 4 frames, 100 -> 103

FILE="D:\IMWR\MyFile_"

START=0 # All frames (ie 0 -> 3)
END=0
TYPE = "jpeg"
INFO=False

ImageWriter(File=FILE,Start=START,end=END,type=TYPE,info=INFO) # Output MyFile_000000.jpeg -> MyFile_000003.jpeg
Return last


script 3 [EDIT: play at least 1 frame]

Colorbars().Trim(0,-200) # 200 frames
ShowFrameNumber

FILE="D:\IMWR\MyFile_"
TYPE = "jpeg"
INFO=False

Trim(100,-4) # 100 -> 103

For(i=0,3) {
current_frame=i # kludge to make Imagewriter work (pretend in runtime environment)
k=ImageWriter(File=FILE,Start=i,end=i,type=TYPE,info=INFO) # Output MyFile_000000.jpeg -> MyFile_000003.jpeg
k.ConvertToY8.Averageluma # Kludge to force write files (ImageWriter only writes frame when frame is requested from the ImageWriter result clip)
}

Return MessageClip("All Done")


ImageWriter is not the easiest filter to abuse. [scripts 2 and 3 to write frame filenames relative to 0 rather than 100]
EDIT: Output filenames are 'Tied' to the frame numbers being output [thats why we had to use Trim for filenames relative 0].

Gavino
1st May 2020, 21:23
Damn that Gavino, stays aways for years at a time and then jumps in to spoil my fun.
:devil: :D
What took you so long? LOL

Good to see you've found another use for my 'current_frame' trick too. :)

StainlessS
1st May 2020, 21:28
What took you so long
Well, I thought I had plenty of time, did not anticipate the interloper.

Good to see...
I like to keep that quiet.

Dont be so much a stranger Big G, nice to see you :)

EDIT: Maybe a bit more flexible [writing filenames relative 0].

Colorbars().Trim(0,-200) # 200 frames
ShowFrameNumber
##############
FILE="D:\IMWR\MyFile_"
TYPE = "jpeg"
START=100
END=103 # EDIT: Cannot use 0 here to mean last frame, must use actual end frame number
INFO=False
##############
COUNT=(END-START+1)

Trim(START,-COUNT) # COUNT frames 0->3, , original numbers 100 -> 103

For(i=0,COUNT-1) {
current_frame=i # kludge to make Imagewriter work (pretend in runtime environment)
k=ImageWriter(File=FILE,Start=i,end=i,type=TYPE,info=INFO) # Output MyFile_000000.jpeg -> MyFile_000003.jpeg
k.ConvertToY8.Averageluma # Kludge to force write files (ImageWriter only writes frame when frame is requested from the ImageWriter result clip)
# OR MAYBE a bit quicker
# k.crop(0,0,4,4).ConvertToY8.Averageluma
}

Return MessageClip("All Done, "+String(COUNT)+" Frames Written")

Oops, fixed filename comment.
EDIT: The AverageLuma forces a frame fetch of the result current_frame frame of ImageWriter, AverageLuma requires Luma so convertToY8 just to allow Averageluma to work for eg RGB.

Georgiana
6th May 2020, 20:12
Dear Gavino and StainlessS, thank you very much for all your time and help! Your answers helped me a lot to better understand how to work with ImageWriter from AviSynth! So thank you again!

rgr
8th April 2025, 17:52
# k.crop(0,0,4,4).ConvertToY8.Averageluma
}

Return MessageClip("All Done, "+String(COUNT)+" Frames Written")
[/CODE]
Oops, fixed filename comment.
EDIT: The AverageLuma forces a frame fetch of the result current_frame frame of ImageWriter, AverageLuma requires Luma so convertToY8 just to allow Averageluma to work for eg RGB.

AverageLuma didn't work for me (it gave an error that it only works with runtime filters - or something like that).
ConvertTo itself worked. But I ran into a problem that ImageWriter only wrote one frame from the sequence.
I solved it like this:

for (i=0,X) {
tmp1 = ConvertToY8(ConvertBits(8).trim(N+i,length=1)) #forceImageWriter = ConvertToY8(tmp.ConvertBits(8).trim(N,length=X))
}

I don't know if there's a better way.

StainlessS
8th April 2025, 23:00
(it gave an error that it only works with runtime filters - or something like that)
Looks like you missed out this [EDIT: from your modified script, all given scripts worked ok]

current_frame=i # kludge to make Imagewriter work (pretend in runtime environment)

rgr
8th April 2025, 23:11
I didn't realize that it had anything to do with AverageLuma.
Nevertheless, ConvertToY8 alone is enough.

StainlessS
8th April 2025, 23:39
I didn't realize that it had anything to do with AverageLuma.
Nevertheless, ConvertToY8 alone is enough.

Not sure, but think that if already Y8, then convertToY8 would internally be skipped and may fail to fetch the frame because of it.
(and image write missed out)

You missed out entire script so no idea what would happen. (dont bother to include, if it works for U then great).

rgr
10th April 2025, 09:47
Now that's a bigger problem.

How do I save a frame that doesn't appear in the clip later because it's replaced by another one?
I have ideas to merge it into the clip using 100% transparency. Or put it at the bottom of the frame and then cut it out.
But maybe there are simpler ideas?

StainlessS
10th April 2025, 11:42
...
How do I save a frame that doesn't appear in the clip later because it's replaced by another one?
I have ideas to merge it into the clip using 100% transparency. Or put it at the bottom of the frame and then cut it out.
...
No idea what you are asking, clarify.

Gavino
11th April 2025, 00:09
How do I save a frame that doesn't appear in the clip later because it's replaced by another one?
The advantage of SS's approach (ab)using AverageLuma and current_frame (post #5 and script 3 of post #3) is that, unlike with the conventional use of ImageWriter, you can save any frame directly at compile time without that frame being in the final script output at all. [Note that the actual output of those scripts is just a MessageClip().]

StainlessS
11th April 2025, 11:49
...
How do I save a frame that doesn't appear in the clip later because it's replaced by another one?
I have ideas to merge it into the clip using 100% transparency. Or put it at the bottom of the frame and then cut it out.
...
rgr, are you saying that you would like to replace all frames in a run of duplicates, with the frame that those dupes are a duplicate of.
(Ie replace all near dupes with exact dupes).

If so, then see below in BLUE.

Duplicity2(), v2.13, by StainlessS @ Doom9:- https://forum.doom9.org/showthread.php?t=175357

A two faced scheming and double dealing [on your behalf] dupe tool.

Three modes of operation,
0) Write duplicate Frames file only (as single frames or ranges).
1) Replace duplicates with exact duplicates. (Can also write Frames file).
2) Replace duplicates with Interpolated or Blended frames (control via MaxDuplen and MaxInterp). (Can also write Frames file).

Req:-
RT_Stats v2.00_Beta_11 + CallCmd (c) StainlessS,
GSCript, Grunt, (c) Gavino,
MaskTools2, MvTools2, (c) Manoa/Fizick/Pinterf & Others (Pinterf Versions).
RemoveGrain, (c) Kassandro.

GScript not needed if Avs+ [(c) Ultim, Pinterf and others.].
If CallCmd available then will AutoDelete DBase on clip closure, otherwise requires manual deletion.

https://forum.doom9.org/showthread.php?t=175357