我可以将其拖放到Shell脚本中的png2jpg二进制文件是理想的选择。
#1 楼
最好的选择是使用ImageMagick。我不是实际用法专家,但是我知道您几乎可以做任何与图像有关的事情!
一个例子是:
convert image.png image.jpg
将保留原始图像并创建转换后的图像。
对于批量转换,我想你需要使用ImageMagick附带的Mogrify工具。
请记住,这会覆盖旧图像。
命令是:
mogrify -format jpg *.png
#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来指定质量
–史蒂芬·杰弗里斯(Steven Jeffries)
17-10-17在21:31
#5 楼
实际上,您要查找的实际“png2jpg
”命令分为两个命令pngtopnm
和cjpeg
,它们分别是netpbm
和libjpeg-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转换为PNGfind . -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
评论
太棒了,这正是我的追求,并将再次使用。顺便说一句,只是澄清一下(我没有意识到这就是您的意思):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