Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
xiaoqi
/
mp4giftconvert
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
bb769164
authored
Apr 25, 2025
by
xiaoqi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
width
parent
7c519188
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
341 additions
and
26 deletions
Webp2MP42.py
convertAlphaVideo.py
convert_webp_2_mp4.py
open_cv.py
Webp2MP42.py
View file @
bb769164
...
@@ -198,13 +198,16 @@ def parse_anmf_data(webp_info):
...
@@ -198,13 +198,16 @@ def parse_anmf_data(webp_info):
# 打开 WebP 动画文件并解析为 PNG 序列帧
# 打开 WebP 动画文件并解析为 PNG 序列帧
def
webp2png
(
webp_file
,
dir_file
):
# 打开 WebP 动画文件并解析为 PNG 序列帧
def
webp2png
(
webp_file
,
dir_file
,
target_width
=
None
):
# 确保目标目录存在
# 确保目标目录存在
if
Path
(
dir_file
)
.
exists
():
# 不重新生成png,只生成一次
if
Path
(
dir_file
)
.
exists
():
# 不重新生成png,只生成一次
return
True
return
True
os
.
makedirs
(
dir_file
,
exist_ok
=
True
)
os
.
makedirs
(
dir_file
,
exist_ok
=
True
)
# 打开 WebP 文件
# 打开 WebP 文件
img
=
Image
.
open
(
webp_file
)
img
=
Image
.
open
(
webp_file
)
# 检查是否是动画
# 检查是否是动画
if
(
not
getattr
(
img
,
"is_animated"
,
False
))
|
(
img
.
n_frames
<=
1
):
if
(
not
getattr
(
img
,
"is_animated"
,
False
))
|
(
img
.
n_frames
<=
1
):
print
(
"这不是一个动画 WebP 文件"
)
print
(
"这不是一个动画 WebP 文件"
)
...
@@ -215,20 +218,29 @@ def webp2png(webp_file, dir_file):
...
@@ -215,20 +218,29 @@ def webp2png(webp_file, dir_file):
img
.
seek
(
i
)
# 移动到第 i 帧
img
.
seek
(
i
)
# 移动到第 i 帧
frame
=
img
.
copy
()
# 复制当前帧
frame
=
img
.
copy
()
# 复制当前帧
width
,
height
=
frame
.
size
width
,
height
=
frame
.
size
# 检查宽度和高度是否为偶数,如果不是,则调整大小
if
width
%
2
!=
0
:
# 如果 target_width 为 None,则裁剪到最近的能被 8 整除的宽度
width
-=
1
if
target_width
is
None
:
if
height
%
2
!=
0
:
target_width
=
(
width
//
8
)
*
8
# 向下取整到最近的 8 的倍数
height
-=
1
if
target_width
<
8
:
# 确保宽度至少为 8
# 调整图片大小
target_width
=
8
if
width
<
img
.
size
[
0
]
or
height
<
img
.
size
[
1
]:
frame
=
frame
.
crop
((
0
,
0
,
width
,
height
))
# 如果目标宽度大于原图宽度,添加透明背景居中
if
target_width
>
width
:
new_frame
=
Image
.
new
(
"RGBA"
,
(
target_width
,
height
),
(
0
,
0
,
0
,
0
))
offset
=
(
target_width
-
width
)
//
2
new_frame
.
paste
(
frame
,
(
offset
,
0
))
frame
=
new_frame
# 如果目标宽度小于原图宽度,裁剪图片
elif
target_width
<
width
:
frame
=
frame
.
crop
(((
width
-
target_width
)
//
2
,
0
,
(
width
+
target_width
)
//
2
,
height
))
# 构造保存路径
# 构造保存路径
frame_path
=
os
.
path
.
join
(
dir_file
,
f
"frame_{i:03d}.png"
)
frame_path
=
os
.
path
.
join
(
dir_file
,
f
"frame_{i:03d}.png"
)
# 保存为 PNG 文件
# 保存为 PNG 文件
frame
.
save
(
frame_path
,
"PNG"
)
frame
.
save
(
frame_path
,
"PNG"
)
# enhance_png(frame_path)
return
True
return
True
...
@@ -484,7 +496,7 @@ if __name__ == '__main__':
...
@@ -484,7 +496,7 @@ if __name__ == '__main__':
inputDirOrFile
=
inputDirOrFile
.
replace
(
"
\"
"
,
""
)
inputDirOrFile
=
inputDirOrFile
.
replace
(
"
\"
"
,
""
)
start_time
=
time
.
time
()
start_time
=
time
.
time
()
print
(
f
"pvf={p_vf}"
)
print
(
f
"pvf={p_vf}"
)
check_file_or_dir
(
inputDirOrFile
,
""
)
check_file_or_dir
(
inputDirOrFile
,
"
-2
"
)
print
(
f
"耗时:{time.time() - start_time}秒"
)
print
(
f
"耗时:{time.time() - start_time}秒"
)
print
(
f
"mp4大小:{mp4_size_total}"
)
print
(
f
"mp4大小:{mp4_size_total}"
)
print
(
f
"webp大小:{webp_size_total}"
)
print
(
f
"webp大小:{webp_size_total}"
)
...
...
convertAlphaVideo.py
0 → 100644
View file @
bb769164
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import
os
import
subprocess
import
sys
import
shutil
import
argparse
import
cv2
import
numpy
as
np
isDebug
=
False
needZip
=
False
outputVideoPath
=
""
imageDir
=
""
srcPath
=
""
maskPath
=
""
outputPath
=
""
oVideoFilePath
=
""
fps
=
25
bitrate
=
2000
def
main
():
parser
=
argparse
.
ArgumentParser
(
description
=
'manual to this script'
)
parser
.
add_argument
(
'--file'
,
type
=
str
,
default
=
None
)
parser
.
add_argument
(
'--dir'
,
type
=
str
,
default
=
None
)
parser
.
add_argument
(
'--zip'
,
type
=
str2bool
,
nargs
=
'?'
,
const
=
True
,
default
=
False
,
help
=
"Activate zip mode."
)
parser
.
add_argument
(
'--fps'
,
type
=
int
,
default
=
25
)
parser
.
add_argument
(
'--bitrate'
,
type
=
int
,
default
=
2000
)
args
=
parser
.
parse_args
()
print
(
"convertAlphaVideo.py running"
)
global
needZip
needZip
=
args
.
zip
fps
=
args
.
fps
bitrate
=
args
.
bitrate
# print "args.zip: ", args.zip
if
not
args
.
file
is
None
:
parseVideoFile
(
args
.
file
)
elif
not
args
.
dir
is
None
:
parseImageDir
(
args
.
dir
)
else
:
print
(
"params is None!"
)
return
print
(
"finish"
)
def
str2bool
(
v
):
if
isinstance
(
v
,
bool
):
return
v
if
v
.
lower
()
in
(
'yes'
,
'true'
,
't'
,
'y'
,
'1'
):
return
True
elif
v
.
lower
()
in
(
'no'
,
'false'
,
'f'
,
'n'
,
'0'
):
return
False
else
:
raise
argparse
.
ArgumentTypeError
(
'Boolean value expected.'
)
def
help
():
print
(
"help ~"
)
def
parseVideoFile
(
path
):
print
(
">>>>>>> paraseVideoFile, file is
%
s"
%
path
)
parentDir
=
os
.
path
.
basename
(
path
)
parentDir
=
parentDir
.
split
(
'.'
)[
0
]
+
"/"
initDir
(
parentDir
)
videoToImage
(
path
,
imageDir
)
parseImageList
(
imageDir
)
imagesToVideo
(
outputPath
,
oVideoFilePath
)
shutil
.
rmtree
(
parentDir
+
"temp/"
)
print
(
">>>>>> convert alpha video finish, video file path is :
%
s"
%
oVideoFilePath
)
def
parseImageDir
(
path
):
parentDir
=
os
.
path
.
abspath
(
path
)
+
"/"
print
(
">>>>>>> paraseImageDir, dirName is
%
s"
%
parentDir
)
initDir
(
parentDir
)
parseImageList
(
parentDir
)
imagesToVideo
(
outputPath
,
oVideoFilePath
)
shutil
.
rmtree
(
parentDir
+
"temp/"
)
print
(
">>>>>> convert alpha video finish, video file path is :
%
s"
%
oVideoFilePath
)
def
initDir
(
parentDir
):
global
imageDir
imageDir
=
parentDir
+
"temp/imageDir/"
mkdir
(
imageDir
)
global
srcPath
srcPath
=
parentDir
+
"temp/source/"
mkdir
(
srcPath
)
global
maskPath
maskPath
=
parentDir
+
"temp/mask/"
mkdir
(
maskPath
)
global
outputPath
outputPath
=
parentDir
+
"temp/output/"
mkdir
(
outputPath
)
global
outputVideoPath
outputVideoPath
=
parentDir
+
"output/"
mkdir
(
outputVideoPath
)
global
oVideoFilePath
oVideoFilePath
=
outputVideoPath
+
"video.mp4"
def
parseImageList
(
inputPath
):
fileList
=
os
.
listdir
(
inputPath
)
totalLength
=
len
(
fileList
)
progress
=
0
for
fileName
in
fileList
:
if
os
.
path
.
splitext
(
fileName
)[
1
]
==
".png"
:
inputImageFile
=
inputPath
+
fileName
srcImageFile
=
srcPath
+
os
.
path
.
splitext
(
fileName
)[
0
]
+
".jpg"
tempMaskImageFile
=
maskPath
+
os
.
path
.
splitext
(
fileName
)[
0
]
+
"_temp.jpg"
maskImageFile
=
maskPath
+
os
.
path
.
splitext
(
fileName
)[
0
]
+
".jpg"
outputImageFile
=
outputPath
+
os
.
path
.
splitext
(
fileName
)[
0
]
+
".jpg"
removeAlpha
(
inputImageFile
,
srcImageFile
)
if
needZip
:
separateAlphaChannel
(
inputImageFile
,
tempMaskImageFile
)
zipAlphaChannelPro
(
tempMaskImageFile
,
maskImageFile
)
else
:
separateAlphaChannel
(
inputImageFile
,
maskImageFile
)
appendImageLand
(
srcImageFile
,
maskImageFile
,
outputImageFile
)
deleteTempFile
(
srcImageFile
)
deleteTempFile
(
maskImageFile
)
deleteTempFile
(
tempMaskImageFile
)
progress
+=
1
updateProgress
(
progress
,
totalLength
)
def
videoToImage
(
videoPath
,
imageDir
):
command
=
"ffmpeg -i {} -r {} {}
%05
d.png"
.
format
(
videoPath
,
fps
,
imageDir
)
if
isDebug
:
print
(
command
)
ret
=
subprocess
.
Popen
(
command
,
shell
=
True
)
ret
.
communicate
()
def
removeAlpha
(
imageSrc
,
imageDst
):
command
=
"convert {} -background black -alpha remove {}"
.
format
(
imageSrc
,
imageDst
)
if
isDebug
:
print
(
command
)
ret
=
subprocess
.
Popen
(
command
,
shell
=
True
)
ret
.
communicate
()
def
separateAlphaChannel
(
imageFileOne
,
imageFileTwo
):
command
=
"convert {} -channel A -separate {}"
.
format
(
imageFileOne
,
imageFileTwo
)
if
isDebug
:
print
(
command
)
ret
=
subprocess
.
Popen
(
command
,
shell
=
True
)
ret
.
communicate
()
def
zipAlphaChannel
(
imageSrc
,
imageDst
):
srcImage
=
cv2
.
imread
(
imageSrc
)
shape
=
srcImage
.
shape
dstImage
=
np
.
zeros
((
int
(
shape
[
0
]),
int
(
shape
[
1
])
/
3
,
int
(
shape
[
2
])),
np
.
uint8
)
dstShape
=
dstImage
.
shape
height
=
dstShape
[
0
]
width
=
dstShape
[
1
]
channels
=
dstShape
[
2
]
for
row
in
range
(
height
):
for
col
in
range
(
width
):
for
channel
in
range
(
channels
):
dstImage
[
row
][
col
][
channel
]
=
srcImage
[
row
][
col
*
3
+
channel
][
0
]
cv2
.
imwrite
(
imageDst
,
dstImage
)
def
zipAlphaChannelPro
(
imageSrc
,
imageDst
):
srcImage
=
cv2
.
imread
(
imageSrc
)
shape
=
srcImage
.
shape
dstImage
=
np
.
zeros
((
int
(
shape
[
0
]),
int
(
shape
[
1
])
/
3
,
int
(
shape
[
2
])),
np
.
uint8
)
dstShape
=
dstImage
.
shape
height
=
dstShape
[
0
]
width
=
dstShape
[
1
]
channels
=
dstShape
[
2
]
for
row
in
range
(
height
):
for
col
in
range
(
width
):
for
channel
in
range
(
channels
):
dstImage
[
row
][
col
][
channel
]
=
srcImage
[
row
][
col
+
channel
*
width
][
0
]
cv2
.
imwrite
(
imageDst
,
dstImage
)
def
appendImageLand
(
imageFileOne
,
imageFileTwo
,
imageFileAppend
):
command
=
"convert +append {} {} {}"
.
format
(
imageFileTwo
,
imageFileOne
,
imageFileAppend
)
if
isDebug
:
print
(
command
)
ret
=
subprocess
.
Popen
(
command
,
shell
=
True
)
ret
.
communicate
()
def
deleteTempFile
(
filePath
):
if
os
.
path
.
exists
(
filePath
):
os
.
remove
(
filePath
)
def
imagesToVideo
(
imagesPath
,
videoFile
):
command
=
"ffmpeg -r {} -i {}
%05
d.jpg -vcodec libx264 -pix_fmt yuv420p -b {}k {}"
.
format
(
fps
,
imagesPath
,
bitrate
,
videoFile
)
if
isDebug
:
print
(
command
)
ret
=
subprocess
.
Popen
(
command
,
shell
=
True
)
ret
.
communicate
()
def
updateProgress
(
progress
,
total
):
percent
=
round
(
1.0
*
progress
/
total
*
100
,
2
)
sys
.
stdout
.
write
(
'
\r
progress :
%
s [
%
d/
%
d]'
%
(
str
(
percent
)
+
'
%
'
,
progress
,
total
))
sys
.
stdout
.
flush
()
def
mkdir
(
path
):
folder
=
os
.
path
.
exists
(
path
)
if
not
folder
:
os
.
makedirs
(
path
)
if
__name__
==
'__main__'
:
main
()
\ No newline at end of file
convert_webp_2_mp4.py
View file @
bb769164
...
@@ -25,6 +25,7 @@ p_tune = "animation"
...
@@ -25,6 +25,7 @@ p_tune = "animation"
p_pix_fmt
=
"yuv444p"
p_pix_fmt
=
"yuv444p"
p_codec
=
"libx264"
p_codec
=
"libx264"
p_enable_sharpening
=
""
# 5:5: 1.5:0: 0:0 //
p_enable_sharpening
=
""
# 5:5: 1.5:0: 0:0 //
p_width
=
None
"""
"""
luma_msize_x:亮度矩阵的水平大小(X方向)。这个值定义了应用于亮度分量的模糊矩阵的宽度。
luma_msize_x:亮度矩阵的水平大小(X方向)。这个值定义了应用于亮度分量的模糊矩阵的宽度。
luma_msize_y:亮度矩阵的垂直大小(Y方向)。这个值定义了应用于亮度分量的模糊矩阵的高度。
luma_msize_y:亮度矩阵的垂直大小(Y方向)。这个值定义了应用于亮度分量的模糊矩阵的高度。
...
@@ -158,7 +159,7 @@ def png2mp4(output_video, fps2, png_dir, target_fps: int = 1000):
...
@@ -158,7 +159,7 @@ def png2mp4(output_video, fps2, png_dir, target_fps: int = 1000):
image_clip
=
ImageSequenceClip
(
image_arrays
,
fps
=
fps
)
image_clip
=
ImageSequenceClip
(
image_arrays
,
fps
=
fps
)
# 创建纯色背景
# 创建纯色背景
background_color
=
(
0
,
0
,
0
)
# 背景颜色(黑)
background_color
=
(
255
,
255
,
255
)
# 背景颜色(黑)
background
=
ColorClip
(
background
=
ColorClip
(
size
=
image_clip
.
size
,
# 背景尺寸与图像帧一致
size
=
image_clip
.
size
,
# 背景尺寸与图像帧一致
color
=
background_color
,
# 背景颜色
color
=
background_color
,
# 背景颜色
...
@@ -224,14 +225,21 @@ def parse_anmf_data(webp_info):
...
@@ -224,14 +225,21 @@ def parse_anmf_data(webp_info):
return
result
return
result
from
PIL
import
Image
,
ImageOps
import
os
from
pathlib
import
Path
# 打开 WebP 动画文件并解析为 PNG 序列帧
# 打开 WebP 动画文件并解析为 PNG 序列帧
def
webp2png
(
webp_file
,
dir_file
):
def
webp2png
(
webp_file
,
dir_file
,
target_width
=
None
):
# 确保目标目录存在
# 确保目标目录存在
if
Path
(
dir_file
)
.
exists
():
# 不重新生成png,只生成一次
if
Path
(
dir_file
)
.
exists
():
# 不重新生成png,只生成一次
return
True
return
True
os
.
makedirs
(
dir_file
,
exist_ok
=
True
)
os
.
makedirs
(
dir_file
,
exist_ok
=
True
)
# 打开 WebP 文件
# 打开 WebP 文件
img
=
Image
.
open
(
webp_file
)
img
=
Image
.
open
(
webp_file
)
# 检查是否是动画
# 检查是否是动画
if
(
not
getattr
(
img
,
"is_animated"
,
False
))
|
(
img
.
n_frames
<=
1
):
if
(
not
getattr
(
img
,
"is_animated"
,
False
))
|
(
img
.
n_frames
<=
1
):
print
(
"这不是一个动画 WebP 文件"
)
print
(
"这不是一个动画 WebP 文件"
)
...
@@ -242,22 +250,30 @@ def webp2png(webp_file, dir_file):
...
@@ -242,22 +250,30 @@ def webp2png(webp_file, dir_file):
img
.
seek
(
i
)
# 移动到第 i 帧
img
.
seek
(
i
)
# 移动到第 i 帧
frame
=
img
.
copy
()
# 复制当前帧
frame
=
img
.
copy
()
# 复制当前帧
width
,
height
=
frame
.
size
width
,
height
=
frame
.
size
# 检查宽度和高度是否为偶数,如果不是,则调整大小
if
width
%
2
!=
0
:
# 如果 target_width 为 None,则裁剪到最近的能被 8 整除的宽度
width
-=
1
if
target_width
is
None
:
if
height
%
2
!=
0
:
target_width
=
(
width
//
8
)
*
8
# 向下取整到最近的 8 的倍数
height
-=
1
if
target_width
<
8
:
# 确保宽度至少为 8
# 调整图片大小
target_width
=
8
if
width
<
img
.
size
[
0
]
or
height
<
img
.
size
[
1
]:
frame
=
frame
.
crop
((
0
,
0
,
width
,
height
))
# 如果目标宽度大于原图宽度,添加透明背景居中
if
target_width
>
width
:
new_frame
=
Image
.
new
(
"RGBA"
,
(
target_width
,
height
),
(
0
,
0
,
0
,
0
))
offset
=
(
target_width
-
width
)
//
2
new_frame
.
paste
(
frame
,
(
offset
,
0
))
frame
=
new_frame
# 如果目标宽度小于原图宽度,裁剪图片
elif
target_width
<
width
:
frame
=
frame
.
crop
(((
width
-
target_width
)
//
2
,
0
,
(
width
+
target_width
)
//
2
,
height
))
# 构造保存路径
# 构造保存路径
frame_path
=
os
.
path
.
join
(
dir_file
,
f
"frame_{i:03d}.png"
)
frame_path
=
os
.
path
.
join
(
dir_file
,
f
"frame_{i:03d}.png"
)
# 保存为 PNG 文件
# 保存为 PNG 文件
frame
.
save
(
frame_path
,
"PNG"
)
frame
.
save
(
frame_path
,
"PNG"
)
# enhance_png(frame_path)
return
True
return
True
def
enhance_png
(
png_file_path
):
def
enhance_png
(
png_file_path
):
# 打开原始图片
# 打开原始图片
...
@@ -418,12 +434,17 @@ def webp2mp4core(input_webp_path_str, output_file_path: str = None, output_name:
...
@@ -418,12 +434,17 @@ def webp2mp4core(input_webp_path_str, output_file_path: str = None, output_name:
return
return
# 在临时目录下创建对应的临时文件夹路径
# 在临时目录下创建对应的临时文件夹路径
# 获取系统临时目录
# 获取系统临时目录
temp_dir
=
Path
(
tempfile
.
gettempdir
())
/
"convert_webp4"
if
output_name
is
None
:
dir_name_end
=
""
else
:
dir_name_end
=
output_name
temp_dir
=
Path
(
tempfile
.
gettempdir
())
/
f
"convert_webp4-{dir_name_end}"
temp_png_dir
=
temp_dir
/
webp_path
.
stem
temp_png_dir
=
temp_dir
/
webp_path
.
stem
temp_png_alpha_dir
=
temp_dir
/
f
"alpha_{webp_path.stem}"
temp_png_alpha_dir
=
temp_dir
/
f
"alpha_{webp_path.stem}"
# 使用更新后的临时文件夹路径进行后续操作
# 使用更新后的临时文件夹路径进行后续操作
if
not
webp2png
(
input_webp_path_str
,
temp_png_dir
):
if
not
webp2png
(
input_webp_path_str
,
temp_png_dir
,
target_width
=
p_width
):
return
return
print
(
f
"已经{input_webp_path_str}转成成png帧,保存在{temp_png_dir}"
)
print
(
f
"已经{input_webp_path_str}转成成png帧,保存在{temp_png_dir}"
)
convert_to_grayscale
(
temp_png_dir
,
temp_png_alpha_dir
)
convert_to_grayscale
(
temp_png_dir
,
temp_png_alpha_dir
)
...
@@ -498,7 +519,8 @@ if __name__ == '__main__':
...
@@ -498,7 +519,8 @@ if __name__ == '__main__':
inputDirOrFile
=
inputDirOrFile
.
replace
(
"
\"
"
,
""
)
inputDirOrFile
=
inputDirOrFile
.
replace
(
"
\"
"
,
""
)
start_time
=
time
.
time
()
start_time
=
time
.
time
()
print
(
f
"pvf={p_vf}"
)
print
(
f
"pvf={p_vf}"
)
check_file_or_dir
(
inputDirOrFile
,
""
)
check_file_or_dir
(
inputDirOrFile
,
output_name
=
"-2"
)
print
(
f
"耗时:{time.time() - start_time}秒"
)
print
(
f
"耗时:{time.time() - start_time}秒"
)
print
(
f
"mp4大小:{mp4_size_total}"
)
print
(
f
"mp4大小:{mp4_size_total}"
)
print
(
f
"webp大小:{webp_size_total}"
)
print
(
f
"webp大小:{webp_size_total}"
)
...
...
open_cv.py
0 → 100644
View file @
bb769164
import
cv2
import
os
import
sys
def
encode_images_to_mp4
(
image_folder
,
output_file
,
fps
=
30
):
# 获取图片路径列表
images
=
[
img
for
img
in
os
.
listdir
(
image_folder
)
if
img
.
endswith
((
'.png'
,
'.jpg'
,
'.jpeg'
))]
images
.
sort
()
# 按文件名排序
if
not
images
:
print
(
"未找到图片文件,请检查路径和格式!"
)
return
# 读取第一张图片以获取尺寸
first_image_path
=
os
.
path
.
join
(
image_folder
,
images
[
0
])
frame
=
cv2
.
imread
(
first_image_path
)
if
frame
is
None
:
print
(
f
"无法读取图片: {first_image_path}"
)
return
height
,
width
,
layers
=
frame
.
shape
size
=
(
width
,
height
)
# 定义视频编码器和输出文件
fourcc
=
cv2
.
VideoWriter_fourcc
(
*
'mp4v'
)
# 使用 mp4 编码
video
=
cv2
.
VideoWriter
(
output_file
,
fourcc
,
fps
,
size
)
# 将图片写入视频
for
image_name
in
images
:
image_path
=
os
.
path
.
join
(
image_folder
,
image_name
)
frame
=
cv2
.
imread
(
image_path
)
if
frame
is
not
None
:
video
.
write
(
frame
)
else
:
print
(
f
"跳过无法读取的图片: {image_path}"
)
# 释放资源
video
.
release
()
print
(
f
"视频已生成: {output_file}"
)
if
__name__
==
"__main__"
:
if
len
(
sys
.
argv
)
!=
4
:
print
(
"用法: python encode_to_mp4.py <图片文件夹路径> <输出文件路径> <帧率>"
)
else
:
image_folder
=
sys
.
argv
[
1
]
output_file
=
sys
.
argv
[
2
]
fps
=
int
(
sys
.
argv
[
3
])
encode_images_to_mp4
(
image_folder
,
output_file
,
fps
)
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment