리눅스에서 PNG를 JPG로 일괄 변환


163

리눅스에서 많은 PNG를 JPG로 일괄 변환하는 좋은 방법을 아는 사람이 있습니까? (우분투를 사용하고 있습니다).

쉘 스크립트에 넣을 수있는 png2jpg 바이너리가 이상적입니다.

답변:


237

최선의 방법은 Imagemagick 을 사용하는 것입니다.

나는 실제 사용법의 전문가는 아니지만 이것과 관련된 이미지를 거의 할 수 있다는 것을 알고 있습니다!

예를 들면 다음과 같습니다.

convert image.png image.jpg

변환 된 이미지를 생성 할뿐만 아니라 원본을 유지합니다. 배치에 관해서. 나는 imagemagick에있을 때 같은 명령 줄에서 Mogrify 도구를 사용해야한다고 생각합니다. 이 있다는 사실을 숙지 덮어 기존의 이미지를.

명령은 다음과 같습니다.

mogrify -format jpg *.png  

7
굉장히, 그게 바로 내가 사용하고 다시 사용할 것입니다. 그건 그렇고, 나는 이것이 당신이 의미하는 것을 깨닫지 못했기 때문에 명확히하기 위해 : 변환은 별도의 출력 파일을 생성하는 데 사용되며, mogrify는 원본 이미지를 수정하는 데 사용됩니다.
nedned

1
배경이 투명한 png 이미지는 jpg로 올바르게 변환되지 않습니다.
vishnu

4
투명한 배경으로 PNG를 변환하려면 다음 명령을 사용하십시오.mogrify -format jpg -background black -flatten *.png
hyperknot

3
mogrify -format jpeg img.png개의 파일이 있고 file img.*하나의 png, 원본을 그대로 유지하고 새로운 JPEG 파일을 보고 한 후 Linux 상자의 @KevinCox . 그래서 mogrify않습니다 없습니다 이 경우 원본 파일을 덮어 씁니다.
neurino

4
에서 mogrify문서 : " 이 도구에 비슷한입니다 convert(당신이 가진 파일 확장자 변경하지 않는 한 원본 이미지 파일을 덮어 쓸 것을 제외하고 -format에 요청한 변경 사항과 옵션). "
얀코-m

82

몇 가지 솔루션이 더 있습니다.

가장 간단한 해결책은 이미 게시 된 것과 같습니다. 간단한 bash for 루프.

for i in *.png ; do convert "$i" "${i%.*}.jpg" ; done

어떤 이유로 든 bash에서 루프를 피하는 경향이 있으므로 여기에서 이름 맹 글링에 bash를 사용하는 더 유닉스 xargs 접근법이 있습니다.

ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.*}.jpg"'

내가 사용하는 것. GNU Parallel을 사용하여 한 번에 여러 작업을 실행하여 성능을 향상시킵니다. 그것은 많은 시스템에 기본적으로 설치되며 거의 확실하게 당신의 저장소에 있습니다 (주변에 좋은 프로그램입니다).

ls -1 *.png | parallel convert '{}' '{.}.jpg'

작업 수는 기본적으로 프로세스 수입니다. 듀얼 코어 시스템에서 3 개의 작업을 사용하여 더 나은 CPU 사용량을 발견했습니다.

ls -1 *.png | parallel -j 3 convert '{}' '{.}.jpg'

그리고 통계를 원한다면 (ETA, 작업 완료, 작업 당 평균 시간 ...)

ls -1 *.png | parallel --eta convert '{}' '{.}.jpg'

GNU Parallel을 사용하는 경우 다른 구문도 있습니다.

parallel convert '{}' '{.}.jpg' ::: *.png

그리고 다른 버전 (데비안 포함)과 비슷한 문법입니다.

parallel convert '{}' '{.}.jpg' -- *.png

2
for에서 올바른 bash 문자열 확장을 위해 +1입니다. 병렬을 언급하기 위해 다른 upvote를 줄 수 있다면, 그렇게 할 것입니다. 그러나 오타가 하나 있습니다 done. for 루프의 끝에는 필요합니다 . 또한, 병렬 물건, 당신은 사용하지 마십시오 수 ls: 같은 구조와 파이프를 parallel -j 3 --eta convert '{}' '{.}.jpg' ::: *.png(참조 여기에 )
evilsoup

오타 수정. 그건 내가 몰랐던 멋진 문법입니다. bash에서 루프를 사용하지 않는 것을 선호하는 것과 같은 이유로 내가 더 좋아하는 것을 모르겠습니다. 아마도 더 "적절한"방법이기 때문에 솔루션을 넣었지만 나 ls에게 더 의미가 있기 때문에 아마도 나 자신을위한 방법을 고수 할 것입니다.
Kevin Cox

1
... 구문은 GNU 병렬에서만 작동한다는 점에 유의해야합니다. 데비안 및 우분투와 같은 일부 Linux 배포판에 패키지 된 병렬은 실제로 약간 다른 구문 (. --대신 사용)이있는 다른 버전 :::이며 심지어 GNU 병렬 기능의 일부 기능이 부족합니다.
evilsoup

(GNU 패러렐을 패키징하지 않은 배포판에있는 사람들은 여기 의 지침을 사용하여 소스에서 쉽게 설치할 수 있지만 )
evilsoup

가능한 한 많은 버전에서 작동하도록 다시 변경해야한다고 생각합니다.
Kevin Cox

26

convert많은 Linux 배포에서 발견 되는 명령은 ImageMagick 제품군의 일부로 설치됩니다. convert디렉토리의 모든 PNG 파일에서 실행 되고 이중 확장 문제를 피하는 bash 코드는 다음과 같습니다 .

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

8
변환 매뉴얼 페이지에 따르면 "변환 프로그램은 ImageMagick (1) 도구 모음의 구성원입니다."
nedned

1
당신이 올바른지. 어떤 이유로 나는 그것이 다른 도서관의 일부라고 생각했습니다. 위에 게시 한 코드는 디렉토리 내에서 일괄 변환을 자동화하는 올바른 방법입니다.
Marcin

2
bash 확장을 사용하여 다음과 같은 명령을 향상시킬 수 있습니다.for f in *.png; do convert "$f" "${f/%png/jpg}"; done
evilsoup

대소 문자를 구분한다는 것을 기억하십시오. 내 카메라 이름을 * .JPG로 지정하고 처음에는 이것을 인식하지 못했습니다.
tsenapathy

10

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

아마도 가장 좋은 대답은 while read부품을 제거했다면 (부품을 교체하거나 모두 제거) ...
don_crissti

@ don_crissti, 읽는 동안 무엇이 잘못 되었습니까?
Steven Jeffries

100 % 확실한 파일 이름을 다루지 않는 한 오류가 발생하기 쉽고 느리고 (매우 느리게).
don_crissti

기본 JPG 품질은 무엇이며 파일 타임 스탬프를 유지하는 방법은 무엇입니까?
Dan Dascalescu

@DanDascalescu 위의 방법 (마지막 파일 제외)은 파일 이름을 유지하지만 파일 이름 확장자를 바꾸므로 타임 스탬프가 지정된 파일은 괜찮습니다 (항상 복사하여 먼저 테스트하십시오). ImageMagick에 따르면, "기본값은 입력 이미지의 추정 품질을 결정할 수있는 경우 추정 품질을 사용하는 것입니다. 그렇지 않으면 92"( imagemagick.org/script/command-line-options.php#quality ) 품질은 -quality 로 지정할 수 있습니다 <숫자> 여기서 <숫자>는 1에서 100입니다.
Steven Jeffries

8

png2jpg찾고 있는 실제 " "명령은 실제로 pngtopnmand 라고하는 두 개의 명령으로 나뉘며 각각 및 패키지의 cjpeg일부입니다 .netpbmlibjpeg-progs

png2pnm foo.png | cjpeg > foo.jpeg

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

1
결과 *.jpg파일을 원본 파일 옆에 남겨두고 *.png파일 크기 / 품질을 줄이는 방법을 보여 주며 디렉토리 또는 파일 이름의 홀수 문자로 인해 중단되지 않는 심층적 인 재귀 적 디렉토리 한 줄 솔루션에 감사드립니다 .
Joel Purra

5

나의 빠른 해결책 for i in $(ls | grep .png); do convert $i $(echo $i.jpg | sed s/.png//g); done


2
이것은 내가 본 못난, 가장 복잡한 명령 라인 중 하나가 될 가지고있다
evilsoup

1
@evilsoup 솔직히 이것은 쉘 스크립트에 우아합니다. 그것이 복잡하다고 주장하는 것은 불공평합니다.
Max Howell

8
@MaxHowell 남자. 아니요. 다음은 이것의 우아한 버전입니다 for f in ./*.png; do convert "$f" "${f%.*}.jpg"; done.. 즉, 완전히 불필요한 방지 ls, grepsed전화를 (그리고 echo있지만, 내장 떠들썩한의 등 / 아니오 약간의 성능에 영향을 줄 것 IIRC), 2 개 개의 파이프 및 두 개의 서브 쉘를 제거한다, 그리고 적은 입력을 포함한다. 모든 버전의 ls구문 분석이 안전 하지 않기 때문에 조금 더 이식성 이 뛰어납니다.
evilsoup

@evilsoup 나는 정정했다! 잘 했어.
Max Howell

4

수년이 너무 늦었 기 때문에 필자가 작성한이 목적을 위해 특별히 png2jpeg 유틸리티가 있습니다.

@Marcin으로 코드를 적응시키기 :

#!/bin/sh

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

3

일괄 처리의 경우 :

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

그래도 image1.png.jpg와 같은 파일 이름으로 끝납니다.

이것은 bash에서, 아마도 본에서 작동합니다. 다른 쉘에 대해서는 모르지만 유일한 차이점은 루프 구문입니다.


1

파일이 둘 이상의 디렉토리에 걸쳐있을 때 변환하는 데 사용합니다. 원래는 TGA에서 PNG로

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

개념은 find필요한 파일이며 확장명을 제거한 다음에 다시 추가하십시오 xargs. 따라서 PNG를 JPG로 변환하려면 확장명을 변경하고 배경 (이 예제에서는 흰색이지만 변경할 수 있음)을 설정하는 알파 채널을 처리하기 위해 추가로 한 가지 작업을 수행 한 다음 이미지를 병합합니다

find . -name "*.png" -type f | sed 's/\.png$//' | xargs -I% convert %.png -background white -flatten  %.jpg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.