หากคุณไม่สนใจเกี่ยวกับเนื้อหาของรูปภาพ PIL น่าจะเป็นโอเวอร์คิล
ฉันขอแนะนำให้แยกวิเคราะห์ผลลัพธ์ของโมดูล python magic:
>>> t = magic.from_file('teste.png')
>>> t
'PNG image data, 782 x 602, 8-bit/color RGBA, non-interlaced'
>>> re.search('(\d+) x (\d+)', t).groups()
('782', '602')
นี่คือ wrapper รอบ libmagic ซึ่งอ่านไบต์น้อยที่สุดเพื่อระบุลายเซ็นประเภทไฟล์
เวอร์ชันที่เกี่ยวข้องของสคริปต์:
https://raw.githubusercontent.com/scardine/image_size/master/get_image_size.py
[อัปเดต]
อืมน่าเสียดายที่เมื่อนำไปใช้กับ jpegs ด้านบนจะให้ "ข้อมูลภาพ JPEG มาตรฐาน EXIF 2.21" ไม่มีขนาดภาพ! - อเล็กซ์ฟลินท์
ดูเหมือนว่า jpegs จะทนทานต่อเวทมนตร์ :-)
ฉันเห็นสาเหตุ: เพื่อให้ได้ขนาดภาพสำหรับไฟล์ JPEG คุณอาจต้องอ่านไบต์มากกว่าที่ libmagic ชอบอ่าน
พับแขนเสื้อของฉันขึ้นและมาพร้อมกับตัวอย่างข้อมูลที่ยังไม่ผ่านการทดสอบ (รับจาก GitHub)ที่ไม่ต้องใช้โมดูลของบุคคลที่สาม
#-------------------------------------------------------------------------------
# Name: get_image_size
# Purpose: extract image dimensions given a file path using just
# core modules
#
# Author: Paulo Scardine (based on code from Emmanuel VAÏSSE)
#
# Created: 26/09/2013
# Copyright: (c) Paulo Scardine 2013
# Licence: MIT
#-------------------------------------------------------------------------------
#!/usr/bin/env python
import os
import struct
class UnknownImageFormat(Exception):
pass
def get_image_size(file_path):
"""
Return (width, height) for a given img file content - no external
dependencies except the os and struct modules from core
"""
size = os.path.getsize(file_path)
with open(file_path) as input:
height = -1
width = -1
data = input.read(25)
if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
# GIFs
w, h = struct.unpack("<HH", data[6:10])
width = int(w)
height = int(h)
elif ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
and (data[12:16] == 'IHDR')):
# PNGs
w, h = struct.unpack(">LL", data[16:24])
width = int(w)
height = int(h)
elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
# older PNGs?
w, h = struct.unpack(">LL", data[8:16])
width = int(w)
height = int(h)
elif (size >= 2) and data.startswith('\377\330'):
# JPEG
msg = " raised while trying to decode as JPEG."
input.seek(0)
input.read(2)
b = input.read(1)
try:
while (b and ord(b) != 0xDA):
while (ord(b) != 0xFF): b = input.read(1)
while (ord(b) == 0xFF): b = input.read(1)
if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
input.read(3)
h, w = struct.unpack(">HH", input.read(4))
break
else:
input.read(int(struct.unpack(">H", input.read(2))[0])-2)
b = input.read(1)
width = int(w)
height = int(h)
except struct.error:
raise UnknownImageFormat("StructError" + msg)
except ValueError:
raise UnknownImageFormat("ValueError" + msg)
except Exception as e:
raise UnknownImageFormat(e.__class__.__name__ + msg)
else:
raise UnknownImageFormat(
"Sorry, don't know how to get information from this file."
)
return width, height
[อัปเดต 2019]
ตรวจสอบการใช้งาน Rust: https://github.com/scardine/imsz
.open()
อ่านไฟล์ทั้งหมดลงในหน่วยความจำ ... (นั่นคือสิ่งที่.load()
) ทำ - เท่าที่ฉันรู้ - นี่ดีพอ ๆ กับการใช้งานPIL