파일이 유효한 이미지 파일인지 확인하는 방법은 무엇입니까?


105

현재 PIL을 사용하고 있습니다.

from PIL import Image
try:
    im=Image.open(filename)
    # do stuff
except IOError:
    # filename not an image file

그러나 이것은 대부분의 경우를 충분히 포함하지만 xcf, svg 및 psd와 같은 일부 이미지 파일은 감지되지 않습니다. Psd 파일에서 OverflowError 예외가 발생합니다.

어떻게 든 그들을 포함시킬 수 있습니까?


21
다른 언어에서 중복을 닫는 것은 특히 일반적인 관행이 아닙니다. 이것으로 다른 파이썬 질문을 찾을 수 없다면 당신이 게시 한 질문에 맞지 않는 사람들이 게시하고 싶어하는 파이썬 특정 솔루션이있을 수 있으므로 열어 두십시오.
— Paolo Bergantino

예, 우선 나는 내가 : P에 대해 몰랐던 파이썬 라이브러리를 정말로 바라고 있었고 벤이 지적했듯이 마법의 숫자는 전체 이미지를 검증하지 않습니다.
— Sujoy

@Sujoy, 컴퓨터가 올바른 컬러 픽셀과 1과 0의 왜곡 된 세트 사이의 차이를 알 수 없기 때문에 모든 컨트롤이있는 한 전체 이미지의 유효성을 검사하는 것은 거의 불가능합니다. (마법의 숫자) 맞습니다.
— DevinB

@devinb, 동의했습니다. 다른 사람이 리팩터링을 요청하는 더 나은 방법을 제시하지 않는 한 매직 넘버를 얻고 끝낼 것입니다. :)
— Sujoy

xcf 및 psd는 실제로 이미지가 아니라 (종종 많은) 이미지를 포함하는 프로젝트 파일입니다 ...하지만 svg에 대한 사례를 만들 수 있습니다.
— mgalgs

답변:


11

많은 경우 처음 몇 개의 문자는 다양한 파일 형식에 대한 마법의 숫자가 될 것입니다. 위의 예외 검사 외에도 이것을 확인할 수 있습니다.


10
"유효한"이미지를 실제로 테스트하는 경우에는 충분하지 않습니다. 예를 들어 매직 넘버가 있다고해서 파일이 잘리지 않았다는 보장은 없습니다.
— Ben Blank

1
훌륭한 조언, 이제 그 숫자가 무엇인지 알아 내면됩니다. 감사합니다 :)
— Sujoy

@ben, 아야 나는 그것을 아직 생각하지 않았다. 참으로 좋은 점입니다
— Sujoy

@Ben, 라이브러리가 파일이 잘 렸음을 어떻게 추측 할 수 있습니까?
— DevinB

6
@Ben Blank : 맞습니다.하지만 99 %의 문제를 해결하는 것이 전혀 해결하지 않는 것보다 낫습니다.
— Brian R. Bondy

205

방금 내장 imghdr 모듈을 찾았습니다 . 파이썬 문서에서 :

imghdr 모듈은 파일 또는 바이트 스트림에 포함 된 이미지 유형을 결정합니다.

작동 방식 :

>>> import imghdr
>>> imghdr.what('/tmp/bass')
'gif'

유사한 기능을 다시 구현하는 것보다 모듈을 사용하는 것이 훨씬 낫습니다.


2
예 imghdr은 대부분의 이미지 형식에서 작동하지만 전부는 아닙니다. SVG, XCF 및 PSD 파일 내 원래의 문제에 따라, 물론 그뿐만 아니라 imghdr에 들키지 않고있다
— Sujoy

2
당신의 대답은 실제로 더 좋습니다. 감사합니다. 누군가가 위에서 말했듯이 ...하지만 방법의 문제를 99 %를 해결하면 모든 .. 그것을 해결하는 더 나은 다음 종종있다
— RinkyPinku

2
주목할만한 가치 : 주어진 이미지 파일 유형이 인식되지 않으면 imghdr.what(path)반환 None합니다 path. 현재 인식되는 이미지 유형 목록 : rgb , gif , pbm , pgm , ppm , tiff , rast , xbm , jpeg , bmp , png , webp , exr .
— patryk.beza

1
조심해! 유효한 HDR 올바른 이미지를 의미하지 않는다 (예를 들어, 이미지 바이트는 스크램블되어 있습니다!)
— 필리포 MAZZA

1
@FilippoMazza의 의견에 따르면 전송 중에 잘린 불량 이미지가이 테스트를 통과 할 수 있지만 PIL이 읽으려고하면 깨질 수 있음을 확인할 수 있습니다.
— kevinmicke

47

Brian이 제안한 것 외에도 PIL의 확인 방법을 사용 하여 파일이 손상 되었는지 확인할 수 있습니다 .

im.verify ()

이미지 데이터를 실제로 디코딩하지 않고 파일이 손상되었는지 확인합니다. 이 메서드가 문제를 발견하면 적절한 예외가 발생합니다. 이 방법은 새로 열린 이미지에서만 작동합니다. 이미지가 이미로드 된 경우 결과는 정의되지 않습니다. 또한이 방법을 사용한 후 이미지를로드해야하는 경우 이미지 파일을 다시 열어야합니다. 속성


주된 문제는 svg, xcf 및 psd 파일을 Image.open ()으로 열 수 없으므로 im.verify ()로 확인할 기회가 없다는 것입니다.
— Sujoy

16
세상에 PIL 문서는 끔찍합니다. "적합한 예외"란 정확히 무엇입니까?
— Timmmm

다음 은 Image.verify ()에 대한 Pillow 문서 링크 입니다. 안타깝게도 더 나을 수는 없으며 아무것도 추가하지 않고 위의 단락을 해제 한 것처럼 보입니다.
— Two-Bit Alchemist

손상된 png 파일에 대한 SyntaxError 발생 확인 확인
— Carl

"실제로 이미지 데이터를 디코딩하는 것"을 확인하는 방법이 있습니까?
— 트레버 보이드 스미스

7

부가 적으로 PIL이미지하면이 같은 파일 이름 확장명 검사를 추가 할 수 있습니다 확인 :

filename.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'))

이것은 파일 이름에 유효한 이미지 확장자가 있는지 확인하고 유효한 이미지인지 확인하기 위해 실제로 이미지를 열지 않습니다. 그래서 추가로 사용 PIL하거나 다른 답변에서 제안한 라이브러리 중 하나 를 사용해야 합니다.


파일의 확장자가 올바르지 않으면 어떻게합니까? 예를 들어, 텍스트 파일은 .jpg 확장자로 저장되거나 그 반대로 저장됩니다.
— hafiz031

1
@ hafiz031 실제 형식을 얻으려면 from PIL import Image img = Image.open(filename) print(img.format)다음과 같이 확인하십시오.img.format.lower() in ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'gif']
— tsveti_iko

불행히도 이것은 나를 위해 작동하지 않았습니다. 여전히 손상된 이미지를 JPEG 이미지로 식별하고 있습니다. 마지막으로이 경우를 다음과 같이 처리했습니다 (OpenCv를 사용 중입니다). stackoverflow.com/a/63421847/6907424
— hafiz031

6

최신 정보

또한 GitHub의 Python 스크립트에서 다음 솔루션을 구현했습니다 .

또한 손상된 파일 (jpg)은 종종 '깨진'이미지가 아닌지 확인했습니다. 즉, 손상된 사진 파일이 때때로 합법적 인 사진 파일로 남아 있고 원본 이미지가 손실되거나 변경되었지만 오류없이로드 할 수 있다는 것을 확인했습니다. 그러나 파일 잘림으로 인해 항상 오류가 발생합니다.

업데이트 종료

대부분의 이미지 형식과 함께 Python Pillow (PIL) 모듈을 사용하여 파일이 유효하고 손상되지 않은 이미지 파일인지 확인할 수 있습니다.

깨진 이미지도 감지하려는 경우 @Nadia Alramli가 im.verify()방법을 올바르게 제안 하지만 가능한 모든 이미지 결함을im.verify 감지하지는 못합니다. 예를 들어 잘린 이미지는 감지하지 못합니다 (대부분의 시청자는 종종 회색 영역으로로드 됨).

Pillow 는 이러한 유형의 결함도 감지 할 수 있지만 이미지 조작 또는 이미지 디코딩 / 리코딩을 적용하거나 검사를 트리거해야합니다. 마지막으로이 코드를 사용하는 것이 좋습니다.

try:
  im = Image.load(filename)
  im.verify() #I perform also verify, don't know if he sees other types o defects
  im.close() #reload is necessary in my case
  im = Image.load(filename) 
  im.transpose(PIL.Image.FLIP_LEFT_RIGHT)
  im.close()
except: 
  #manage excetions here

이미지 결함의 경우이 코드는 예외를 발생시킵니다. im.verify가 이미지 조작을 수행하는 것보다 약 100 배 더 빠르다는 것을 고려하십시오 (그리고 플립이 더 저렴한 변환 중 하나라고 생각합니다). 이 코드를 사용하면 표준 Pillow를 사용하는 경우 약 10 MBytes / sec, Pillow-SIMD 모듈 (최신 2.5Ghz x86_64 CPU)을 사용하는 경우 40 MBytes / sec의 이미지 집합을 확인할 수 있습니다.

다른 형식 psd , xcf , ..의 경우 Imagemagick wrapper Wand를 사용할 수 있습니다 . 코드는 다음과 같습니다.

im = wand.image.Image(filename=filename)
temp = im.flip;
im.close()

그러나 내 실험에서 Wand는 잘린 이미지를 감지하지 못하기 때문에 부족한 부분을 프롬프트없이 회색 영역으로로드한다고 생각합니다.

나는 그 빨간 있는 Imagemagick가 외부 명령이 식별 그 수있는 일을,하지만 난 프로그램이 함수를 호출하는 방법을 발견하지 않은 나는이 경로를 테스트하지 않았습니다.

항상 예비 검사를 수행하고 파일 크기 가 0 (또는 매우 작음)이 아닌지 확인 하는 것이 매우 저렴한 아이디어입니다.

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case

4

Linux 에서는 libmagic을 사용하여 파일 형식을 식별하는 python-magic ( http://pypi.python.org/pypi/python-magic/0.1 )을 사용할 수 있습니다.

AFAIK, libmagic은 파일을 살펴보고 비트 맵 크기, 형식 버전 등과 같은 형식보다 더 많은 정보를 알려줍니다. 따라서 "유효성"에 대한 피상적 인 테스트로 볼 수 있습니다.

"유효"의 다른 정의에 대해서는 자체 테스트를 작성해야 할 수도 있습니다.


4

Python 바인딩을 libmagic, python-magic 에 사용한 다음 MIME 유형을 확인할 수 있습니다. 파일이 손상되었거나 손상되지 않았는지 알려주지는 않지만 어떤 유형의 이미지인지 확인할 수 있어야합니다.


3

글쎄요, 저는 psd의 내부에 대해 모르지만 사실, svg는 그 자체로 이미지 파일이 아니라는 것을 압니다.-그것은 xml에 기반을두고 있습니다. 일반 텍스트 파일.


아하, 당신 말이 맞아요. xml입니다. 그러나 여기에는 일부 이미지 데이터가 포함되어 있습니다.
— Sujoy

2

한 가지 옵션은 filetype패키지 를 사용하는 것 입니다.

설치

python -m pip install filetype

장점

  1. 빠른 : 이미지의 처음 몇 바이트를로드하여 작업을 수행 합니다 (매직 넘버 확인 ).
  2. 이미지, 비디오, 글꼴, 오디오, 아카이브 등 다양한 MIME 유형을 지원합니다.

솔루션 예

import filetype

filename = "/path/to/file.jpg"

if filetype.image(filename):
    print(f"{filename} is a valid image...")
elif filetype.video(filename):
    print(f"{filename} is a valid video...")

공식 저장소에 대한 추가 정보 : https://github.com/h2non/filetype.py


1

파일 확장자를 확인하는 것이 허용됩니까 아니면 데이터 자체가 이미지 파일을 나타내는 지 확인하려고합니까?

파일 확장자를 확인할 수있는 경우 정규 표현식이나 간단한 비교가 요구 사항을 충족 할 수 있습니다.


txt 파일의 이름을 jpg 또는 다른 이름으로 바꿀 수 있으므로 확장자를 확인하는 것만으로는 충분하지 않습니다. 나는 해결책을 찾을 수없는 경우에만 xcf 및 svg에 대한 확장 검사를 사용할 것입니다
— Sujoy

이해할 수 있습니다. 귀하의 요구에 더 잘 맞는 솔루션을 고안하기 전에 몇 가지 설명을 바랐습니다. 감사!
— doomspork

-1
format = [".jpg",".png",".jpeg"]
 for (path,dirs,files) in os.walk(path):
     for file in files:
         if file.endswith(tuple(format)):
             print(path)
             print ("Valid",file)
         else:
             print(path)
             print("InValid",file)

코드에 들여 쓰기 문제가있어 제대로 실행되지 않습니다. 또한 코드가 문제를 해결하는 이유와 방법에 대한 설명을 추가해보십시오. 코드 전용 답변은 여기에 오는 미래의 독자에게 그렇게 도움이되지 않습니다.
— Tomerikoo

여기에서는 Agrparser 방법을 사용했습니다.
— rObinradOO
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.