如何使用 FFMPEG+Imagemagick 从 image/video 中提取有组织的调色板?
How to extract organized palette from image/video with FFMPEG+Imagemagick?
我使用 FFMPEG 和 Imagemagick 通过 Windows 批处理文件从图像或视频中提取调色板,
:: get current folder name
for %%* in (.) do set CurrDirName=%%~nx*
:: get current filename
for /R %1 %%f in (.) do (
set CurrFileName=%%~nf
)
ffmpeg -i "%1" -vf palettegen "_%CurrFileName%_temp_palette.png"
convert "_%CurrFileName%_temp_palette.png" -filter point -resize 4200%% "_%CurrFileName%_palette.png"
del "_%CurrFileName%_temp_palette.png"
这输出类似,
我需要它在整个色块中有更好的过渡,就像所有的蓝色从最暗到最亮然后过渡到绿色、黄色等,比如,
是否有 way/switch 可以用 Imagemagick/FFMPEG 创建这个?
我不喜欢研究 Windows,但我想向您展示一种您可以使用的技术。因此,我用 bash
编写了它,但几乎避免了所有 Unix-y 的内容,并使它变得非常简单。为了在 Windows 上 运行 它,您只需要 ImageMagick 和 awk
以及 sort
,您可以从 here and here 获得 Windows。
我将使用脚本在第三行附近创建的随机数据图像进行演示:
这是脚本。它的评论很好,如果您喜欢它的功能,应该很容易转换为 Windows。
#!/bin/bash
# Create an initial image of random data 100x100
convert -size 100x100 xc:gray +noise random image.png
# Extract unique colours in image and convert to HSL colourspace and thence to text for "awk"
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" '
!/^#/{
H=; S=; L= # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}' > groupHSL.txt
# Sort by column 1 (group) then by column 4 (Lightness)
sort -n -k1,1 -k4,4 < groupHSL.txt > groupHSL-sorted.txt
# Reassemble the sorted pixels back into a simple image, 16-bit PNM format of HSL data
# Discard the group in column 1 () that we used to sort the data
awk ' { H[++i]=; S[i]=; L[i]= }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}' groupHSL-sorted.txt > HSL.pnm
# Convert HSL.pnm to sRGB.png
convert HSL.pnm -set colorspace hsl -colorspace sRGB sRGB.png
# Make squareish shape
convert sRGB.png -crop 1x1 miff:- | montage -geometry +0+0 -tile 40x - result.png
如果我将 NGROUPS
设置为 10,我得到:
如果我将 NGROUPS 设置为 4,我得到:
请注意,脚本生成中间文件而不是使用管道和 shell 技巧,因此您可以轻松查看处理的每个阶段以便对其进行调试。
例如,如果您 运行 这个:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | more
您将看到 convert
传递给 awk
的输出:
# ImageMagick pixel enumeration: 10000,1,255,hsl
0,0: (257,22359,1285) #015705 hsl(1.41176,34.1176%,1.96078%)
1,0: (0,0,1542) #000006 hsl(0,0%,2.35294%)
2,0: (41634,60652,1799) #A2EC07 hsl(228.706,92.549%,2.7451%)
3,0: (40349,61166,1799) #9DEE07 hsl(221.647,93.3333%,2.7451%)
4,0: (31868,49858,2056) #7CC208 hsl(175.059,76.0784%,3.13725%)
5,0: (5140,41377,3341) #14A10D hsl(28.2353,63.1373%,5.09804%)
6,0: (61423,59367,3598) #EFE70E hsl(337.412,90.5882%,5.4902%)
如果你看一下 groupHSL-sorted.txt
,你会看到像素是如何被分类成组然后增加亮度的:
0 0 53456 10537
0 0 18504 20303
0 0 41377 24158
0 0 21331 25700
0 0 62708 28270
0 0 53199 31354
0 0 23130 32896
0 0 8738 33410
0 0 44204 36494
0 0 44204 36751
0 0 46260 38293
0 0 56283 40606
0 0 53456 45489
0 0 0 46517
0 0 32896 46517
0 0 16191 50372
0 0 49601 55769
0 257 49601 11565
0 257 42148 14392
0 257 53713 14649
0 257 50115 15677
0 257 48830 16191
Windows 在引用东西时特别笨拙——尤其是单引号中的脚本,就像我上面为 awk
使用的那样。我建议您将两个单独的 awk
脚本提取到单独的文件中,如下所示:
script1.awk
!/^#/{
H=; S=; L= # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}
和
script2.awk
{ H[++i]=; S[i]=; L[i]= }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}
那么主脚本中的两行会变成这样:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" -f script1.awk > groupHSL.txt
和
awk -f script2.awk groupHSL-sorted.txt > HSL.pnm
我使用 FFMPEG 和 Imagemagick 通过 Windows 批处理文件从图像或视频中提取调色板,
:: get current folder name
for %%* in (.) do set CurrDirName=%%~nx*
:: get current filename
for /R %1 %%f in (.) do (
set CurrFileName=%%~nf
)
ffmpeg -i "%1" -vf palettegen "_%CurrFileName%_temp_palette.png"
convert "_%CurrFileName%_temp_palette.png" -filter point -resize 4200%% "_%CurrFileName%_palette.png"
del "_%CurrFileName%_temp_palette.png"
这输出类似,
我需要它在整个色块中有更好的过渡,就像所有的蓝色从最暗到最亮然后过渡到绿色、黄色等,比如,
是否有 way/switch 可以用 Imagemagick/FFMPEG 创建这个?
我不喜欢研究 Windows,但我想向您展示一种您可以使用的技术。因此,我用 bash
编写了它,但几乎避免了所有 Unix-y 的内容,并使它变得非常简单。为了在 Windows 上 运行 它,您只需要 ImageMagick 和 awk
以及 sort
,您可以从 here and here 获得 Windows。
我将使用脚本在第三行附近创建的随机数据图像进行演示:
这是脚本。它的评论很好,如果您喜欢它的功能,应该很容易转换为 Windows。
#!/bin/bash
# Create an initial image of random data 100x100
convert -size 100x100 xc:gray +noise random image.png
# Extract unique colours in image and convert to HSL colourspace and thence to text for "awk"
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" '
!/^#/{
H=; S=; L= # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}' > groupHSL.txt
# Sort by column 1 (group) then by column 4 (Lightness)
sort -n -k1,1 -k4,4 < groupHSL.txt > groupHSL-sorted.txt
# Reassemble the sorted pixels back into a simple image, 16-bit PNM format of HSL data
# Discard the group in column 1 () that we used to sort the data
awk ' { H[++i]=; S[i]=; L[i]= }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}' groupHSL-sorted.txt > HSL.pnm
# Convert HSL.pnm to sRGB.png
convert HSL.pnm -set colorspace hsl -colorspace sRGB sRGB.png
# Make squareish shape
convert sRGB.png -crop 1x1 miff:- | montage -geometry +0+0 -tile 40x - result.png
如果我将 NGROUPS
设置为 10,我得到:
如果我将 NGROUPS 设置为 4,我得到:
请注意,脚本生成中间文件而不是使用管道和 shell 技巧,因此您可以轻松查看处理的每个阶段以便对其进行调试。
例如,如果您 运行 这个:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | more
您将看到 convert
传递给 awk
的输出:
# ImageMagick pixel enumeration: 10000,1,255,hsl
0,0: (257,22359,1285) #015705 hsl(1.41176,34.1176%,1.96078%)
1,0: (0,0,1542) #000006 hsl(0,0%,2.35294%)
2,0: (41634,60652,1799) #A2EC07 hsl(228.706,92.549%,2.7451%)
3,0: (40349,61166,1799) #9DEE07 hsl(221.647,93.3333%,2.7451%)
4,0: (31868,49858,2056) #7CC208 hsl(175.059,76.0784%,3.13725%)
5,0: (5140,41377,3341) #14A10D hsl(28.2353,63.1373%,5.09804%)
6,0: (61423,59367,3598) #EFE70E hsl(337.412,90.5882%,5.4902%)
如果你看一下 groupHSL-sorted.txt
,你会看到像素是如何被分类成组然后增加亮度的:
0 0 53456 10537
0 0 18504 20303
0 0 41377 24158
0 0 21331 25700
0 0 62708 28270
0 0 53199 31354
0 0 23130 32896
0 0 8738 33410
0 0 44204 36494
0 0 44204 36751
0 0 46260 38293
0 0 56283 40606
0 0 53456 45489
0 0 0 46517
0 0 32896 46517
0 0 16191 50372
0 0 49601 55769
0 257 49601 11565
0 257 42148 14392
0 257 53713 14649
0 257 50115 15677
0 257 48830 16191
Windows 在引用东西时特别笨拙——尤其是单引号中的脚本,就像我上面为 awk
使用的那样。我建议您将两个单独的 awk
脚本提取到单独的文件中,如下所示:
script1.awk
!/^#/{
H=; S=; L= # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}
和
script2.awk
{ H[++i]=; S[i]=; L[i]= }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}
那么主脚本中的两行会变成这样:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" -f script1.awk > groupHSL.txt
和
awk -f script2.awk groupHSL-sorted.txt > HSL.pnm