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


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.