Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

ตรวจสอบประเภทไฟล์ภาพใน Python ด้วยโมดูล imghdr

โมดูล imghdr ใน Python standard library ใช้ระบุประเภทไฟล์ภาพจากเนื้อหาไฟล์ (ไม่ใช่แค่ดู副檔名) รองรับ JPEG, PNG, GIF, TIFF, BMP, และอื่นๆ

ติดตั้งและตรวจสอบ

# Python 3.6+ มาพร้อมกับ imghdr แล้ว (standard library)
# หากไม่มี ให้ติดตั้ง (ไม่ค่อยพบ)
pip install imghdr

# ทดสอบ
>>> import imghdr
>>>

ฟังก์ชันหลัก: imghdr.what()

imghdr.what(filename[, h])
พารามิเตอร์ คำอธิบาย
filenameพาธไฟล์ภาพ
h (optional)byte stream ของภาพ (ถ้าระบุ จะไม่ใช้ filename)

ค่าที่คืน:

  • String ชื่อ format (เช่น 'jpeg', 'png', 'gif')
  • None หากระบุไม่ได้

รูปแบบภาพที่รองรับ

ค่าที่คืน รูปแบบภาพ
'rgb'SGI ImgLib Files
'gif'GIF 87a และ 89a
'pbm'Portable Bitmap
'pgm'Portable Graymap
'ppm'Portable Pixmap
'tiff'TIFF Files
'rast'Sun Raster Files
'xbm'X Bitmap Files
'jpeg'JPEG (JFIF หรือ Exif)
'bmp'BMP Files
'png'Portable Network Graphics

ตัวอย่างการใช้งาน

1. ตรวจสอบไฟล์เดียว

import imghdr

print(imghdr.what('clock.jpg'))   # 'jpeg'
print(imghdr.what('logo.png'))    # 'png'
print(imghdr.what('animation.gif')) # 'gif'
print(imghdr.what('document.pdf'))  # None (ไม่ใช่ภาพ)

2. ใช้กับ Byte Stream (ไม่ต้องเซฟไฟล์)

import imghdr
import requests

response = requests.get('https://example.com/image.jpg')
img_type = imghdr.what(None, h=response.content)
print(img_type)  # 'jpeg'

3. ใช้งานจริง: ดาวน์โหลดและตรวจสอบประเภทไฟล์

import imghdr
import os
import requests

def identify_filetype(url, image_name, folder_name):
    session = requests.Session()
    try:
        # ดาวน์โหลดภาพ
        response = session.get(url, timeout=5)
        response.raise_for_status()
        
        # เซฟชั่วคราว
        temp_path = os.path.join(folder_name, image_name)
        with open(temp_path, 'wb') as f:
            f.write(response.content)
        
        # ตรวจสอบประเภท
        file_ext = imghdr.what(temp_path)
        
        if file_ext is None:
            # ไม่ใช่ภาพ -> ลบ
            os.remove(temp_path)
            print(f"Removed non-image: {url}")
        else:
            # เปลี่ยนชื่อให้มี extension ถูกต้อง
            new_name = f"{image_name}.{file_ext}"
            new_path = os.path.join(folder_name, new_name)
            os.rename(temp_path, new_path)
            print(f"Saved as: {new_name}")
            
    except Exception as e:
        print(f"Failed to download {url}: {e}")

# ใช้งาน
identify_filetype('https://example.com/photo', 'image_001', 'downloads')

4. สแกนโฟลเดอร์หาไฟล์ภาพเฉพาะประเภท

import imghdr
from pathlib import Path

def find_jpeg_files(folder):
    jpeg_files = []
    for file_path in Path(folder).rglob('*'):
        if file_path.is_file():
            img_type = imghdr.what(file_path)
            if img_type == 'jpeg':
                jpeg_files.append(file_path)
    return jpeg_files

# ใช้งาน
jpegs = find_jpeg_files('/path/to/photos')
for f in jpegs:
    print(f)

ขยายการรองรับ: imghdr.tests

สามารถเพิ่มการตรวจจับรูปแบบใหม่ได้โดยเพิ่มฟังก์ชันเข้า imghdr.tests

import imghdr

def test_webp(h, f):
    """ตรวจจับ WebP: เริ่มต้นด้วย 'RIFF' และมี 'WEBP' ที่ offset 8"""
    if h.startswith(b'RIFF') and h[8:12] == b'WEBP':
        return 'webp'
    return None

# เพิ่มเข้าไปใน tests
imghdr.tests.append(test_webp)

# ทดสอบ
print(imghdr.what('image.webp'))  # 'webp'

ข้อจำกัด

  • ตรวจสอบจาก magic bytes (header) ไม่ได้ลึกถึง pixel data
  • ไม่รองรับรูปแบบใหม่ๆ เช่น WebP, AVIF, HEIC (ต้องเพิ่มเอง)
  • Python 3.11+ deprecated imghdr แนะนำใช้ filetype หรือ python-magic แทน

ทางเลือกสมัยใหม่

# filetype library (แนะนำ)
pip install filetype
import filetype
kind = filetype.guess('image.jpg')
print(kind.mime)    # image/jpeg
print(kind.extension) # jpg

# python-magic (ใช้ libmagic system library)
pip install python-magic
import magic
print(magic.from_file('image.jpg', mime=True))  # image/jpeg