Roemer
30th April 2021, 11:46
Hello all
I am in the process of wrinting a small method that allows processing frames externally (for example with imagemagick or waifu2x).
Basically you pass the clip, the path to the executable and the arguments with two placehoders (input and output image) and that's it.
I am actually doing a good progress and it is already kind of working. The only thing that is a bit hacky is if the external application modifies the size. The hacky solution is to read the file in a separate clip, resize the original clip and only then replace the current image. Also I am fairly unsure with the colorformates. I do a ConvertToRGB24 before saving the image with ImageWriter and then convert to ConvertToYV12.
Feedback / Ideas are greatly welcomed!
Examples:
# Example for imagemagick
ProcessImageExternal("C:\ImageMagick\convert.exe", "-verbose [EXPORTEDIMAGEPATH] -grayscale Rec709Luminance [PROCESSEDIMAGEPATH]", debug=false)
# Example for Waifu2X
ProcessImageExternal("C:\waifu2x-converter-cpp\waifu2x-converter-cpp.exe", "-m noise-scale -v 1 --noise-level 2 --scale-ratio 3 -i [EXPORTEDIMAGEPATH] -o [PROCESSEDIMAGEPATH]", debug=false)
Function:
###
# Method that extracts the current image, processes it with an external application and reads the file back in.
# It will run in the directory of the external application so dependencies should all work.
# Parameters
# - executablePath: The full path to the executable
# - arguments: The argument string to pass to the executable.
# Must include [EXPORTEDIMAGEPATH] which will be replaced with the quoted path to the image that is exported
# and [PROCESSEDIMAGEPATH] which will be replaced with the quoted path to the image that is processed
# - tempDirectory: Optional. The path for the temp directory to use for the image files.
# - tempFileName: Optional. The base name of the temp file to use.
###
function ProcessImageExternal(clip c, string executablePath, string arguments, string "tempDirectory", string "tempFileName", bool "debug")
{
tempDirectory = default(tempDirectory, "C:\Temp\")
tempFileName = default(tempFileName, "avs_extimageexport")
debug = default(debug, false)
# Build the image path of the exported image
exportedImagePath = tempDirectory + tempFileName + "%..bmp" # Needed for the image writer to force it to not use numbering
exportedImagePath2 = tempDirectory + tempFileName + ".bmp"
processedImagePath = tempDirectory + tempFileName + "_processed.png"
# Export the current frame as image
c.ConvertToRGB24()
ScriptClip(Format("""ImageWriter("{exportedImagePath}", start=current_frame, end=current_frame)"""), after_frame=true).ConvertToYV12()
# Get the executable working directory and name
indexOfLastSlash = FindStr(RevStr(executablePath), "\") - 1
executableName = RightStr(executablePath, indexOfLastSlash)
executableDirectory = LeftStr(executablePath, StrLen(executablePath) - indexOfLastSlash)
# Execute the external application
arguments = ReplaceStr(arguments, "[EXPORTEDIMAGEPATH]", Format(""""{exportedImagePath2}""""))
arguments = ReplaceStr(arguments, "[PROCESSEDIMAGEPATH]", Format(""""{processedImagePath}""""))
if (debug) {
CallCmd(Format("""cmd /k start "" /wait /b /d "{executableDirectory}" "{executableDirectory}{executableName}" {arguments}"""), "0,0", Hide=false)
} else {
CallCmd(Format("""cmd /c start "" /wait /b /d "{executableDirectory}" "{executableDirectory}{executableName}" {arguments}"""), "0,0", Hide=true)
}
# Read the file in a temporary clip in order to get the size
fileTemp = ImageSourceAnim(processedImagePath)
# Resize the "current" clip before assigning it the new processed image
Lanczos4Resize(fileTemp.Width(), fileTemp.Height())
# Load the processed image into the clip
ScriptClip(Format("""ImageSourceAnim("{processedImagePath}").ConvertToYV12()"""), after_frame =true)
}
I am in the process of wrinting a small method that allows processing frames externally (for example with imagemagick or waifu2x).
Basically you pass the clip, the path to the executable and the arguments with two placehoders (input and output image) and that's it.
I am actually doing a good progress and it is already kind of working. The only thing that is a bit hacky is if the external application modifies the size. The hacky solution is to read the file in a separate clip, resize the original clip and only then replace the current image. Also I am fairly unsure with the colorformates. I do a ConvertToRGB24 before saving the image with ImageWriter and then convert to ConvertToYV12.
Feedback / Ideas are greatly welcomed!
Examples:
# Example for imagemagick
ProcessImageExternal("C:\ImageMagick\convert.exe", "-verbose [EXPORTEDIMAGEPATH] -grayscale Rec709Luminance [PROCESSEDIMAGEPATH]", debug=false)
# Example for Waifu2X
ProcessImageExternal("C:\waifu2x-converter-cpp\waifu2x-converter-cpp.exe", "-m noise-scale -v 1 --noise-level 2 --scale-ratio 3 -i [EXPORTEDIMAGEPATH] -o [PROCESSEDIMAGEPATH]", debug=false)
Function:
###
# Method that extracts the current image, processes it with an external application and reads the file back in.
# It will run in the directory of the external application so dependencies should all work.
# Parameters
# - executablePath: The full path to the executable
# - arguments: The argument string to pass to the executable.
# Must include [EXPORTEDIMAGEPATH] which will be replaced with the quoted path to the image that is exported
# and [PROCESSEDIMAGEPATH] which will be replaced with the quoted path to the image that is processed
# - tempDirectory: Optional. The path for the temp directory to use for the image files.
# - tempFileName: Optional. The base name of the temp file to use.
###
function ProcessImageExternal(clip c, string executablePath, string arguments, string "tempDirectory", string "tempFileName", bool "debug")
{
tempDirectory = default(tempDirectory, "C:\Temp\")
tempFileName = default(tempFileName, "avs_extimageexport")
debug = default(debug, false)
# Build the image path of the exported image
exportedImagePath = tempDirectory + tempFileName + "%..bmp" # Needed for the image writer to force it to not use numbering
exportedImagePath2 = tempDirectory + tempFileName + ".bmp"
processedImagePath = tempDirectory + tempFileName + "_processed.png"
# Export the current frame as image
c.ConvertToRGB24()
ScriptClip(Format("""ImageWriter("{exportedImagePath}", start=current_frame, end=current_frame)"""), after_frame=true).ConvertToYV12()
# Get the executable working directory and name
indexOfLastSlash = FindStr(RevStr(executablePath), "\") - 1
executableName = RightStr(executablePath, indexOfLastSlash)
executableDirectory = LeftStr(executablePath, StrLen(executablePath) - indexOfLastSlash)
# Execute the external application
arguments = ReplaceStr(arguments, "[EXPORTEDIMAGEPATH]", Format(""""{exportedImagePath2}""""))
arguments = ReplaceStr(arguments, "[PROCESSEDIMAGEPATH]", Format(""""{processedImagePath}""""))
if (debug) {
CallCmd(Format("""cmd /k start "" /wait /b /d "{executableDirectory}" "{executableDirectory}{executableName}" {arguments}"""), "0,0", Hide=false)
} else {
CallCmd(Format("""cmd /c start "" /wait /b /d "{executableDirectory}" "{executableDirectory}{executableName}" {arguments}"""), "0,0", Hide=true)
}
# Read the file in a temporary clip in order to get the size
fileTemp = ImageSourceAnim(processedImagePath)
# Resize the "current" clip before assigning it the new processed image
Lanczos4Resize(fileTemp.Width(), fileTemp.Height())
# Load the processed image into the clip
ScriptClip(Format("""ImageSourceAnim("{processedImagePath}").ConvertToYV12()"""), after_frame =true)
}