在linux中批量转换PNG到JPG

ned*_*ned 199 linux png jpeg shell-script

有谁知道在 linux 中将一堆 PNG 批量转换为 JPG 的好方法吗?(我正在使用 Ubuntu)。

我可以直接放入 shell 脚本的 png2jpg 二进制文件是理想的。

Wil*_*sum 296

您最好的选择是使用ImageMagick

我不是实际使用方面的专家,但我知道你几乎可以做任何与图像相关的事情!

一个例子是:

convert image.png image.jpg
Run Code Online (Sandbox Code Playgroud)

这将保留原始图像并创建转换后的图像。

至于批量转换,我认为您需要使用ImageMagick 中的Mogrify工具。

请记住,这会覆盖旧图像。

命令是:

mogrify -format jpg *.png
Run Code Online (Sandbox Code Playgroud)

  • 太棒了,这正是我所追求的,并将再次使用。顺便说一下,为了澄清,因为我没有意识到这就是你的意思:convert 用于生成单独的输出文件,mogrify 用于修改原始图像。 (7认同)
  • 来自 `mogrify` 文档:“*这个工具类似于 `convert`,除了原始图像文件会被你请求的任何更改覆盖(除非你使用 **-format** 选项更改文件后缀)。*” (7认同)
  • 要转换具有透明背景的 PNG,请使用以下命令:`mogrify -format jpg -background black -flatten *.png` (6认同)
  • @KevinCox 在`mogrify -format jpeg img.png` 之后在我的 linux 机器上,我有 2 个文件,并且 `file img.*` 报告一个 png,原始未修改,和一个新的 jpeg。所以在这种情况下,`mogrify` **不** 覆盖原始文件。 (4认同)
  • 如果你需要压缩你的 png 的更多使用 `mogrify -quality 75 -format jpg *.png` (3认同)

Kev*_*Cox 99

我还有几个解决方案。

最简单的解决方案就像大多数已经发布的一样。一个简单的 bash for 循环。

for i in *.png ; do convert "$i" "${i%.*}.jpg" ; done
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我倾向于避免 bash 中的循环,所以这里有一个更 unixy xargs 的方法,使用 bash 进行名称修改。

ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.*}.jpg"'
Run Code Online (Sandbox Code Playgroud)

我用的那个。它使用 GNU Parallel 一次运行多个作业,从而提高性能。它默认安装在许多系统上,并且几乎肯定在您的存储库中(这是一个很好的程序)。

ls -1 *.png | parallel convert '{}' '{.}.jpg'
Run Code Online (Sandbox Code Playgroud)

作业数默认为您拥有的 CPU 内核数。我在我的双核系统上使用 3 个作业发现了更好的 CPU 使用率。

ls -1 *.png | parallel -j 3 convert '{}' '{.}.jpg'
Run Code Online (Sandbox Code Playgroud)

如果你想要一些统计数据(预计到达时间、完成的工作、每项工作的平均时间......)

ls -1 *.png | parallel --eta convert '{}' '{.}.jpg'
Run Code Online (Sandbox Code Playgroud)

如果您使用 GNU Parallel,还有另一种语法。

parallel convert '{}' '{.}.jpg' ::: *.png
Run Code Online (Sandbox Code Playgroud)

以及其他一些版本(包括 debian)的类似语法。

parallel convert '{}' '{.}.jpg' -- *.png
Run Code Online (Sandbox Code Playgroud)

  • +1 用于 for 中正确的 bash 字符串扩展,如果我能给你另一个提到并行的赞成票,我会的。但是,有一个错字 - 您需要在 for 循环结束时使用 `done`。另外,对于并行的东西,你可以避免使用 `ls` 和带有类似结构的管道:`parallel -j 3 --eta convert '{}' '{.}.jpg' ::: *.png` (见[这里](http://www.gnu.org/software/parallel/man.html#example__reading_arguments_from_command_line)) (2认同)

Mar*_*cin 26

convert在许多 Linux 发行版上找到的命令是作为 ImageMagick 套件的一部分安装的。这是convert在目录中的所有 PNG 文件上运行的 bash 代码,并避免双重扩展问题:

for img in *.png; do
    filename=${img%.*}
    convert "$filename.png" "$filename.jpg"
done
Run Code Online (Sandbox Code Playgroud)

  • 根据转换的手册页:“转换程序是 ImageMagick(1) 工具套件的成员。” (8认同)
  • 您可以使用 bash 扩展来改进该命令,例如:`for f in *.png; 做转换 "$f" "${f/%png/jpg}"; 完成` (2认同)

Ste*_*ies 14

tl;博士

对于那些只想要最简单命令的人:

转换保留原始文件:

mogrify -format jpg *.png
Run Code Online (Sandbox Code Playgroud)

转换删除原始文件:

mogrify -format jpg *.png && rm *.png
Run Code Online (Sandbox Code Playgroud)

批量转换说明

参加聚会有点晚,但只是为了让那些可能对 cli 不太舒服的人感到困惑,这里有一个超级愚蠢的参考和解释。

示例目录

bar.png
foo.png
foobar.jpg
Run Code Online (Sandbox Code Playgroud)

简单转换

保留所有原始 png 文件以及创建 jpg 文件。

mogrify -format jpg *.png
Run Code Online (Sandbox Code Playgroud)

结果

bar.png
bar.jpg
foo.png
foo.jpg
foobar.jpg
Run Code Online (Sandbox Code Playgroud)

解释

  • mogrifyImageMagick图像处理工具套件的一部分。
    • mogrify 处理图像就地,这意味着原始文件被覆盖,-format选项除外。(从网站This tool is similar to convert except that the original image file is overwritten (unless you change the file suffix with the -format option)
  • - format选项指定您将更改格式,下一个参数需要是类型(在本例中为 jpg)。
  • 最后*.png是输入文件(所有以 .png 结尾的文件)。

转换和删除

将所有 png 文件转换为 jpg,删除原始文件。

mogrify -format jpg *.png && rm *.png
Run Code Online (Sandbox Code Playgroud)

结果

bar.jpg
foo.jpg
foobar.jpg
Run Code Online (Sandbox Code Playgroud)

解释

  • 第一部分与上面完全相同,它将创建新的 jpg 文件。
  • &&是一个布尔运算符。简而言之:
    • 当程序终止时,它返回一个退出状态。状态0表示没有错误。
    • 由于&&执行短路评估,只有在没有错误的情况下才会执行正确的部分。这很有用,因为如果转换它们时出现错误,您可能不想删除所有原始文件。
  • rm命令删除文件。

花哨的东西

现在,这里是对谁的人一些东西舒适的CLI。

如果您在转换文件时想要一些输出:

for i in *.png; do mogrify -format jpg "$i" && rm "$i"; echo "$i converted to ${i%.*}.jpg"; done
Run Code Online (Sandbox Code Playgroud)

转换所有子目录中的所有 png 文件并为每个文件提供输出:

find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; echo "Converted $i to ${i%.*}.jpg"; done
Run Code Online (Sandbox Code Playgroud)

转换所有子目录中的所有 png 文件,将所有生成的 jpg 放入all目录中,编号,删除原始 png 文件,并在每个文件发生时显示输出:

n=0; find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; fn="all/$((n++)).jpg"; mv "${i%.*}.jpg" "$fn"; echo "Moved $i to $fn"; done
Run Code Online (Sandbox Code Playgroud)


Ted*_*ddy 8

png2jpg您正在寻找的实际“ ”命令实际上分为两个名为pngtopnmand 的命令cjpeg,它们分别是netpbmandlibjpeg-progs包的一部分。

png2pnm foo.png | cjpeg > foo.jpeg
Run Code Online (Sandbox Code Playgroud)


小智 7

find . -name "*.png" -print0 | xargs -0 mogrify -format jpg -quality 50
Run Code Online (Sandbox Code Playgroud)

  • 感谢深度/递归目录单行解决方案,它将生成的 `*.jpg` 文件放在原始的 `*.png` 文件旁边,展示了如何减小文件大小/质量并且不会因为任何奇怪的字符而中断在目录或文件名中。 (2认同)

小智 5

我的快速解决方案 for i in $(ls | grep .png); do convert $i $(echo $i.jpg | sed s/.png//g); done

  • @MaxHowell 人。不。这是一个优雅的版本:`for f in ./*.png; 做转换 "$f" "${f%.*}.jpg"; 完成`。这避免了完全不必要的 `ls`、`grep` 和 `sed` 调用(以及 `echo`,但 IIRC 是 bash 内置的,因此不会/几乎没有性能影响),并摆脱了两个管道和两个子外壳, * 和 * 涉及较少的打字。它甚至更易于移植,因为并非所有版本的 `ls` 都可以安全地解析。 (8认同)
  • 这一定是我见过的最丑陋、最复杂的命令行之一 (2认同)