ffmpeg:在具有自定义透明度的视频上叠加 png 图像?
ffmpeg: overlay a png image on a video with custom transparency?
假设我有一个视频 foo.mkv
和一个图像 bar.png
(恰好包含一个 alpha 通道)。我可以像这样将此图像混合到视频中:
ffmpeg
-i foo.mkv
-i bar.png
-filter_complex "[0:v][1:v]overlay"
-vcodec libx264
myresult.mkv
(为了便于阅读,这里使用多行,通常这是一个命令行)。
现在,除了 png 图像有自己的 alpha 通道外,我还会在视频上混合此图像时应用自定义 整体透明度。
在上面的示例中,图像将在视频顶部 100% 可见——或者至少是其 Alpha 通道完全不透明的部分。
有没有办法添加自定义的整体不透明度或透明度混合因子,例如 opacity=0.5
或其他任何东西,这将使图像只有 50% 可见?
我想我明白了:
ffmpeg
-i foo.mkv
-i bar.png
-filter_complex "[1:v]format=argb,geq=r='r(X,Y)':a='0.5*alpha(X,Y)'[zork];
[0:v][zork]overlay"
-vcodec libx264
myresult.mkv
其中 0.5
是不透明度系数。我包括 format=argb
,因此它也适用于本身没有 alpha 通道的叠加图像。
除geq
之外的另一个选项是colorchannelmixer
。
[1:v]format=argb,colorchannelmixer=aa=0.5[zork]
使用此函数在 FFmpeg 视频中叠加具有透明度的图像 Android
fun addimagemerge(inputVideo: String, imageInput: String, output: String): Array<String> {
val inputs: ArrayList<String> = ArrayList()
inputs.apply {
add("-i")
add(inputVideo)
add("-i")
add(imageInput)
add("-filter_complex")
add("[1:v]format=argb,geq=r='r(X,Y)':a='0.5*alpha(X,Y)'[zork]; [0:v][zork]overlay")
add("-preset")
add("ultrafast")
add(output)
}
return inputs.toArray(arrayOfNulls<String>(inputs.size))
}
将其用于转换按钮上的调用函数
val outputPath = getFilePath(this, VIDEO)
val query = ffmpegQueryExtension.addimagemerge(
selectedVideoPath!!,
selectedImagePath!!,
outputPath
)
CallBackOfQuery().callQuery(this, query, object : FFmpegCallBack {
override fun process(logMessage: LogMessage) {
runOnUiThread {
tvOutputPath.text = logMessage.text
}
}
override fun success() {
tvOutputPath.text = String.format(getString(R.string.output_path), outputPath)
processStop()
runOnUiThread {
videoPlayclass.stopVideoPlay(bottmLay, videoPlayAct)
videoPlayclass.videoPlayStart(
this@MergeImageVideoActivity,
bottmLay,
videoPlayAct,
outputPath
)
}
}
override fun cancel() {
processStop()
}
override fun failed() {
processStop()
}
})
假设我有一个视频 foo.mkv
和一个图像 bar.png
(恰好包含一个 alpha 通道)。我可以像这样将此图像混合到视频中:
ffmpeg
-i foo.mkv
-i bar.png
-filter_complex "[0:v][1:v]overlay"
-vcodec libx264
myresult.mkv
(为了便于阅读,这里使用多行,通常这是一个命令行)。
现在,除了 png 图像有自己的 alpha 通道外,我还会在视频上混合此图像时应用自定义 整体透明度。
在上面的示例中,图像将在视频顶部 100% 可见——或者至少是其 Alpha 通道完全不透明的部分。
有没有办法添加自定义的整体不透明度或透明度混合因子,例如 opacity=0.5
或其他任何东西,这将使图像只有 50% 可见?
我想我明白了:
ffmpeg
-i foo.mkv
-i bar.png
-filter_complex "[1:v]format=argb,geq=r='r(X,Y)':a='0.5*alpha(X,Y)'[zork];
[0:v][zork]overlay"
-vcodec libx264
myresult.mkv
其中 0.5
是不透明度系数。我包括 format=argb
,因此它也适用于本身没有 alpha 通道的叠加图像。
除geq
之外的另一个选项是colorchannelmixer
。
[1:v]format=argb,colorchannelmixer=aa=0.5[zork]
使用此函数在 FFmpeg 视频中叠加具有透明度的图像 Android
fun addimagemerge(inputVideo: String, imageInput: String, output: String): Array<String> {
val inputs: ArrayList<String> = ArrayList()
inputs.apply {
add("-i")
add(inputVideo)
add("-i")
add(imageInput)
add("-filter_complex")
add("[1:v]format=argb,geq=r='r(X,Y)':a='0.5*alpha(X,Y)'[zork]; [0:v][zork]overlay")
add("-preset")
add("ultrafast")
add(output)
}
return inputs.toArray(arrayOfNulls<String>(inputs.size))
}
将其用于转换按钮上的调用函数
val outputPath = getFilePath(this, VIDEO)
val query = ffmpegQueryExtension.addimagemerge(
selectedVideoPath!!,
selectedImagePath!!,
outputPath
)
CallBackOfQuery().callQuery(this, query, object : FFmpegCallBack {
override fun process(logMessage: LogMessage) {
runOnUiThread {
tvOutputPath.text = logMessage.text
}
}
override fun success() {
tvOutputPath.text = String.format(getString(R.string.output_path), outputPath)
processStop()
runOnUiThread {
videoPlayclass.stopVideoPlay(bottmLay, videoPlayAct)
videoPlayclass.videoPlayStart(
this@MergeImageVideoActivity,
bottmLay,
videoPlayAct,
outputPath
)
}
}
override fun cancel() {
processStop()
}
override fun failed() {
processStop()
}
})