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

我可以将其拖放到Shell脚本中的png2jpg二进制文件是理想的选择。

#1 楼

最好的选择是使用ImageMagick。

我不是实际用法专家,但是我知道您几乎可以做任何与图像有关的事情!

一个例子是:

convert image.png image.jpg


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

对于批量转换,我想你需要使用ImageMagick附带的Mogrify工具。

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

命令是:

mogrify -format jpg *.png


评论


太棒了,这正是我的追求,并将再次使用。顺便说一句,只是澄清一下(我没有意识到这就是您的意思):convert用于生成单独的输出文件,mogrify用于修改原始图像。

–nedned
09年11月16日下午4:11

要使用透明背景转换PNG,请使用以下命令:mogrify -format jpg -background black -flatten * .png

–超结
2012年6月26日18:54

我的Linux机器上的@KevinCox迁移-format jpeg img.png后,我有2个文件,文件img。*报告一个png,原始未更改,另一个是jpeg。因此,在这种情况下,mogrify不会覆盖原始文件。

–neurino
13年8月28日在6:54



来自mogrify文档:“此工具可以进行转换,只是原始图像文件被覆盖(除非您使用-format选项更改了文件后缀),并且可以进行任何请求的更改。”

– janko-m
2014-09-18 17:07



如果您需要更多压缩png,请使用mogrify -quality 75 -format jpg * .png

– Flatron
16年6月20日在7:43

#2 楼

我还有几个解决方案。
最简单的解决方案就像大多数已经发布的解决方案一样。一个简单的bash for循环。
for i in *.png ; do convert "$i" "${i%.*}.jpg" ; done

由于某种原因,我倾向于避免在bash中循环,因此这是一种更加统一的xargs方法,使用bash进行名称修改。
ls -1 *.png | xargs -n 1 bash -c 'convert "
ls -1 *.png | parallel convert '{}' '{.}.jpg'
" "${0%.*}.jpg"'

我用的那个。它使用GNU Parallel一次运行多个作业,从而提高了性能。默认情况下,它已安装在许多系统上,并且几乎肯定在您的存储库中(这是个不错的程序)。
ls -1 *.png | parallel -j 3 convert '{}' '{.}.jpg'

作业数默认为您拥有的CPU内核数。我在双核系统上使用3个作业发现了更好的CPU使用率。
ls -1 *.png | parallel --eta convert '{}' '{.}.jpg'

如果您需要一些统计信息(ETA,已完成的作业,每个作业的平均时间...)
parallel convert '{}' '{.}.jpg' ::: *.png

如果您使用的是GNU Parallel,则还有另一种语法。
parallel convert '{}' '{.}.jpg' -- *.png

,某些其他版本(包括debian)也有类似的语法。
q4312078q

评论


为for中正确的bash字符串扩展+1,如果我可以再提一提并行性,我会赞成。但是,有一个错别字-您需要在for循环的最后完成操作。另外,对于并行的东西,您可以避免将ls和pipe与类似的结构一起使用:parallel -j 3 --eta convert'{}''{。}。jpg'::: * .png(请参见此处)

– evilsoup
13年1月28日在3:04



固定错别字。我不知道这是一个很酷的语法。我不知道我更喜欢哪一个,可能出于相同的原因,我更喜欢在bash中不使用循环。我把它作为解决方案,因为它可能是更“正确”的方法,但我可能会坚持使用ls方法,因为它对我来说更有意义。

–凯文·考克斯(Kevin Cox)
13年1月28日在14:04

...尽管应注意,语法仅适用于GNU并行。在某些Linux发行版(例如Debian和Ubuntu)中打包的并行实际上是一个具有稍微不同的语法的不同版本(使用-而不是:: :)-即使这样,它仍然令人沮丧地缺少GNU parallel的某些功能。

– evilsoup
13年1月28日在14:17

(尽管发行版中不打包GNU parallel的发行版可以使用此处的说明从源代码很容易地安装它)

– evilsoup
13年1月28日在14:24

我认为我应该在那时更改它,以便它可以与尽可能多的版本一起使用。

–凯文·考克斯(Kevin Cox)
13年1月28日在18:16

#3 楼

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

for img in *.png; do
    filename=${img%.*}
    convert "$filename.png" "$filename.jpg"
done


评论


根据convert的手册页:“ convert程序是ImageMagick(1)工具套件的成员。”

–nedned
09年11月16日在4:06

你是对的。由于某种原因,我认为它是另一个库的一部分。无论哪种方式,我上面发布的代码都是在目录中自动进行批量转换的正确方法。

–马辛
09年11月16日下午4:17

您可以使用bash扩展来改进该命令,例如:* .png中的f;确实要转换“ $ f”“ $ {f /%png / jpg}”;完成

– evilsoup
13年1月28日在2:57

只要记住它是区分大小写的即可。我的相机将其命名为* .JPG,但一开始并没有意识到这一点。

–精神病
16-3-27在1:07



#4 楼

tl; dr

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

转换并保留原始文件:

mogrify -format jpg *.png


转换并删除原始文件:

mogrify -format jpg *.png && rm *.png


分批转换解释

金达迟到聚会,但只是为了消除所有混乱对于可能对cli不太满意的人,这里有个超级精简的参考和解释。

示例目录

bar.png
foo.png
foobar.jpg


简单转换

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

mogrify -format jpg *.png


结果

bar.png
bar.jpg
foo.png
foo.jpg
foobar.jpg


说明




mogrify是ImageMagick图像处理工具套件的一部分。


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


结果

bar.jpg
foo.jpg
foobar.jpg


解释


第一部分是与上面完全相同,它将创建新的jpg文件。
&&是布尔运算符。简而言之:


程序终止时,它将返回退出状态。 0的状态表示没有错误。
由于&&进行了短路评估,因此只有在没有错误的情况下才执行右侧部分。这很有用,因为如果在转换原始文件时出错,您可能不想删除所有原始文件。


rm命令将删除文件。

花式东西

现在,这是给那些适应气候变化的人们提供的好东西。

如果要在转换文件时输出一些信息:

for i in *.png; do mogrify -format jpg "$i" && rm "$i"; echo "$i converted to ${i%.*}.jpg"; done


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

find . -iname '*.png' | while read i; do mogrify -format jpg "$i" && rm "$i"; echo "Converted $i to ${i%.*}.jpg"; done


转换所有子目录中的所有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


评论


如果您摆脱了已阅读的部分(替换或全部删除),可能是最好的答案...

–don_crissti
15-10-26在12:07

@don_crissti,阅读时出了什么问题?

–史蒂芬·杰弗里斯(Steven Jeffries)
15-10-26在13:47

这很容易出错(除非您100%确定要处理的文件名是健全的)且速度很慢(例如非常非常慢)。

–don_crissti
15-10-26在14:01

JPG的默认质量是什么?如何保存文件时间戳?

– Dan Dascalescu
17-10-17在7:24

@DanDascalescu上面的方法(最后一个方法除外)将保留文件名,但替换其扩展名,因此带有时间戳的文件应该可以(总是先进行复制和测试)。根据ImageMagick的说法,“默认情况下,如果可以确定输入图像,则默认使用估计的图像质量,否则为92”(imagemagick.org/script/command-line-options.php#quality)可以使用-quality来指定质量,其中是1到100。

–史蒂芬·杰弗里斯(Steven Jeffries)
17-10-17在21:31

#5 楼

实际上,您要查找的实际“ png2jpg”命令分为两个命令pngtopnmcjpeg,它们分别是netpbmlibjpeg-progs软件包的一部分。

png2pnm foo.png | cjpeg > foo.jpeg


#6 楼

find . -name "*.png" -print0 | xargs -0 mogrify -format jpg -quality 50


评论


感谢您提供深度/递归目录单行解决方案,该解决方案使生成的* .jpg文件与原始* .png文件相邻,展示了如何减小文件大小/质量并且不会由于目录或文件中的任何奇数字符而中断名称。

–乔尔·普拉(Joel Purra)
2014年12月28日15:21

#7 楼

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

评论


这一定是我见过的最丑陋,最复杂的命令行之一

– evilsoup
13年1月28日在2:56

@evilsoup说实话,这对于shell脚本来说很优雅。声称它是令人费解的是不公平的。

– Max Howell
13年5月5日在17:31

@MaxHowell男人。不会。这是一个优雅的版本:对于./*.png中的f;确实要转换“ $ f”“ $ {f%。*}。jpg”;完成。这避免了完全不必要的ls,grep和sed调用(以及echo,但是IIRC是内置的bash,因此对性能的影响很小/很小),并且摆脱了两个管道和两个子shell,并且减少了键入工作。由于不是所有版本的ls都可以安全解析,因此它甚至更具可移植性。

– evilsoup
13年11月6日在12:08



@evilsoup我站纠正了!做得好。

– Max Howell
2013年11月6日14:58

#8 楼

许多年为时已晚,我专门为此目的创建了一个png2jpeg实用程序。

@Marcin修改代码:

 #!/bin/sh

for img in *.png
do
    filename=${img%.*}
    png2jpeg -q 95 -o "$filename.jpg" "$filename.png"
done
 


#9 楼

对于批处理:

for img in *.png; do
  convert "$img" "$img.jpg"
done


您最终将获得像image1.png.jpg这样的文件名。

这将在bash中起作用,也许是伯恩。我不了解其他shell,但是唯一的区别可能是循环语法。

#10 楼

当文件跨越多个目录时,这就是我用来转换的内容。我最初的想法是将TGA转换为PNG

find . -name "*.tga" -type f | sed 's/\.tga$//' | xargs -I% convert %.tga %.png


概念是您find所需的文件,剥离扩展名,然后使用xargs重新添加。因此,对于从PNG到JPG的图片,您需要更改扩展名并做另一件事来处理Alpha通道,即设置背景(在此示例中为白色,但您可以更改它),然后展平图像

find . -name "*.png" -type f | sed 's/\.png$//' | xargs -I% convert %.png -background white -flatten  %.jpg


#11 楼

如果您的PNG是透明的,请尝试在转换之前添加黑色bg:

mogrify -format jpg -background black -flatten *.png


或白色bg:

mogrify -format jpg -background white -flatten *.png


评论


谢谢。最后的评论,但使我免于陷入困境,弄清楚了为什么吗? >>迁移:无法打开图像'jpg:':没有这样的文件或目录@ error / blob.c / OpenBlob / 3496。

– Slabo
20-4-23在21:20