Python Metadata exif



 Metadata ของรูปภาพคืออะไร และ วิธีการดึงข้อมูลนั้นด้วย Python ทีละขั้นตอน 

📸 Metadata Images คืออะไร?

Metadata (เมทาดาต้า) คือ "ข้อมูลเกี่ยวกับข้อมูล" (Data about Data) ซึ่งเป็นข้อมูลที่ถูกฝังอยู่ในไฟล์รูปภาพ (โดยเฉพาะไฟล์ JPEG) 

เพื่ออธิบายรายละเอียดและที่มาที่ไปของรูปภาพนั้น ๆ

ข้อมูล Metadata ของรูปภาพที่สำคัญที่สุดคือ EXIF (Exchangeable Image File Format) ซึ่งถูกสร้างขึ้นโดยอุปกรณ์ที่ใช้ถ่ายภาพ 

เช่น กล้องดิจิทัลหรือสมาร์ทโฟน

ตัวอย่างข้อมูล Metadata (EXIF) ที่สามารถพบได้:

วันที่และเวลาที่ถ่ายภาพ

รุ่นและยี่ห้อของกล้อง (เช่น Canon EOS R5, iPhone 15 Pro)

การตั้งค่ากล้อง (เช่น ความเร็วชัตเตอร์ (Shutter Speed), รูรับแสง (Aperture), ค่า ISO, ความยาวโฟกัส (Focal Length))

ตำแหน่งทางภูมิศาสตร์ (GPS Location) ที่ถ่ายภาพ

ข้อมูลลิขสิทธิ์ หรือชื่อผู้สร้างภาพ (IPTC Metadata)

ความสำคัญของ Metadata:

การจัดระเบียบและการค้นหา: ช่วยให้จัดกลุ่มรูปภาพตามวันที่, สถานที่, หรือกล้องที่ใช้ได้ง่าย

การตรวจสอบ: ใช้ในการตรวจสอบความถูกต้องของภาพ (Fact Check) เพื่อดูว่าภาพถูกตัดต่อหรือไม่ หรือถูกถ่ายเมื่อใดที่ไหน

ข้อมูลเชิงลึก: ช่วยให้นักถ่ายภาพหรือผู้ใช้เข้าใจข้อมูลทางเทคนิคเบื้องหลังการถ่ายภาพนั้น ๆ

🐍 วิธีการดึง Metadata ของรูปภาพด้วย Python

เราสามารถใช้ไลบรารี Pillow (PIL) ซึ่งเป็นไลบรารียอดนิยมในการจัดการรูปภาพใน Python เพื่อดึงข้อมูล EXIF ได้อย่างง่ายดาย

ขั้นตอนการดึงข้อมูลด้วย Python (ใช้ไลบรารี Pillow)

1. การติดตั้งไลบรารีที่จำเป็น

คุณต้องติดตั้งไลบรารี Pillow ก่อน หากยังไม่ได้ติดตั้ง:

pip install Pillow

2. โค้ด Python ทีละขั้นตอน

นี่คือโค้ด Python สำหรับเปิดไฟล์รูปภาพ ดึงข้อมูล EXIF และแปลง Tag ID ให้เป็นชื่อที่อ่านง่าย:


# ***************************************************************** #

คำอธิบายโค้ดโดยละเอียด:

from PIL import Image และ from PIL.ExifTags import TAGS:

Image เป็นคลาสหลักสำหรับเปิดและจัดการรูปภาพ

TAGS เป็น Dictionary ที่ใช้สำหรับแปลงตัวเลข Tag ID (ที่เครื่องเข้าใจ) ให้เป็นชื่อ Tag ที่มนุษย์เข้าใจได้ เช่น 305 กลายเป็น Software

image = Image.open(image_path):

เปิดไฟล์รูปภาพที่ต้องการ

exifdata = image.getexif():

นี่คือฟังก์ชันหลักที่ใช้ดึงข้อมูล EXIF ทั้งหมดออกมา ข้อมูลที่ได้จะเป็น Dictionary ที่มีคีย์เป็นตัวเลข (Tag ID)

for tag_id in exifdata::

วนลูปอ่านทุก Tag ID และ Value ที่ดึงมาได้

tag_name = TAGS.get(tag_id, tag_id):

เรียกดูชื่อ Tag ที่อ่านง่ายจาก Dictionary TAGS ถ้าไม่พบ (เช่น เป็น Tag ที่ไม่มาตรฐาน) จะใช้ Tag ID ตัวเลขนั้นแทน

value = exifdata.get(tag_id):

ดึงค่าที่เกี่ยวข้องกับ Tag นั้น ๆ


#*******************************************************************************#

1. การแปลผลพิกัดสถานที่ (GPS Location)

ค่าที่คุณได้มาเป็นระบบ **องศา (Degrees), ลิปดา (Minutes), ฟิลิปดา (Seconds)** หรือ DMS ซึ่งเราต้องแปลงเป็นทศนิยมเพื่อนำไปค้นหาครับ

GPS Latitude (ละติจูด):** `(14.0, 37.0, 46.36596) N`

GPS Longitude (ลองจิจูด):** `(101.0, 24.0, 34.836119) E`

วิธีการคำนวณ (แปลงจาก DMS เป็น Decimal)

สูตรคือ: องศา + (ลิปดา / 60) + (ฟิลิปดา / 3600)

หาค่าละติจูด (แนวนอน):14 + (37 / 60) + (46.36596 / 3600) = {14.629546}

หาค่าลองจิจูด (แนวตั้ง):101 + (24 / 60) + (34.836119 / 3600) ={101.409677}

ข้อมูลที่ต้องการ,อยู่ใน g_tag_name ชื่อว่า,ค่าที่อยู่ใน g_value

ละติจูด (DMS),GPSLatitude,"(องศา, ลิปดา, ฟิลิปดา)"

ทิศทางละติจูด,GPSLatitudeRef,'N' หรือ 'S'

ลองจิจูด (DMS),GPSLongitude,"(องศา, ลิปดา, ฟิลิปดา)"

ทิศทางลองจิจูด,GPSLongitudeRef,'E' หรือ 'W'

สถานที่โดยประมาณ:** พิกัดนี้อยู่ในเขต **อุทยานแห่งชาติเขาใหญ่ (ฝั่งนครราชสีมา)** ใกล้กับบริเวณอ่างเก็บน้ำสายศร หรือเส้นทางศึกษาธรรมชาติครับ

---

2. ข้อมูลเสริมอื่นๆ จาก GPS

* **GPSAltitude:** `330.3` หมายถึง ความสูงจากระดับน้ำทะเลประมาณ **330 เมตร**

* **GPSTimeStamp:** `(4, 24, 32)` คือเวลา **04:24:32 UTC** (เวลามาตรฐานสากล) หากเทียบเป็นเวลาไทย (UTC+7) จะเป็นเวลาประมาณ **11:24:32 น.** ซึ่งตรงกับ `DateTime` ใน Metadata หลักครับ

* **GPSProcessingMethod (CELLID):** บอกว่าเครื่องใช้วิธีระบุตำแหน่งจาก **"เสาสัญญาณมือถือ"** ร่วมกับ GPS เพื่อความรวดเร็วในการหาพิกัด


---


 3. สรุปภาพรวมจาก Metadata ทั้งหมด

 **อุปกรณ์:** มือถือ Huawei Y7 Pro 2018 (LDN-LX2)

* **วันเวลา:** 12 ตุลาคม 2024 เวลา 11:24 น.

* **สถานที่:** แถวเขาใหญ่ นครราชสีมา (สูงกว่าระดับน้ำทะเล 330 ม.)

* **ขนาดภาพ:** 8 ล้านพิกเซล (อัตราส่วน 3:4)


#*******************************************************************************#

Full Code  ค้นหาข้อมูล meta data 

from PIL import Image

from PIL.ExifTags import TAGS, GPSTAGS


# ฟังก์ชันสำหรับแปลงค่า DMS เป็น Decimal

def convert_to_degrees(value):

    d = float(value[0])

    m = float(value[1])

    s = float(value[2])

    return d + (m / 60.0) + (s / 3600.0)


image_path = "jpg01.jpg" 


try:

    image = Image.open(image_path)

    print(f"กำลังประมวลผลไฟล์: {image.filename}")

    

    exifdata = image.getexif()


    if not exifdata:

        print("ไม่พบข้อมูล EXIF ในรูปภาพนี้")

    else:

        print("\n** ข้อมูล Metadata (EXIF) **")

        gps_info_id = None


        for tag_id in exifdata:

            tag_name = TAGS.get(tag_id, tag_id)

            value = exifdata.get(tag_id)


            if tag_name == "GPSInfo":

                gps_info_id = tag_id


            if isinstance(value, bytes):

                try:

                    value = value.decode('utf-8').strip()

                except UnicodeDecodeError:

                    value = f"<Binary Data - {len(value)} bytes>"


            print(f"{tag_name:<25}: {value}")


        # --- ส่วนที่เพิ่ม: คำนวณและแสดงค่า GPS สำหรับ Google Maps ---

        if gps_info_id:

            gps_data = exifdata.get_ifd(gps_info_id)

            

            # ดึงค่าที่จำเป็นสำหรับการคำนวณ

            lat = gps_data.get(2)  # GPSLatitude

            lat_ref = gps_data.get(1) # GPSLatitudeRef

            lon = gps_data.get(4)  # GPSLongitude

            lon_ref = gps_data.get(3) # GPSLongitudeRef


            if lat and lat_ref and lon and lon_ref:

                lat_dec = convert_to_degrees(lat)

                if lat_ref != 'N': lat_dec = -lat_dec


                lon_dec = convert_to_degrees(lon)

                if lon_ref != 'E': lon_dec = -lon_dec


                print("\n" + "="*50)

                print("** ข้อมูลพิกัดสำหรับ Google Maps **")

                print(f"Latitude (Decimal)  : {lat_dec:.6f}")

                print(f"Longitude (Decimal) : {lon_dec:.6f}")

                print("-" * 30)

                # บรรทัดสำหรับคัดลอกไปวางในช่องค้นหา Google Maps

                print(f"คัดลอกไปวางใน Google Maps: {lat_dec:.6f}, {lon_dec:.6f}")

                # บรรทัดที่เป็น URL สำหรับกดเปิดทันที

                print(f"ลิงก์แผนที่: https://www.google.com/maps?q={lat_dec:.6f},{lon_dec:.6f}")

                print("="*50)


except FileNotFoundError:

    print(f"Error: ไม่พบไฟล์ที่ชื่อ '{image_path}'")

except Exception as e:

    print(f"เกิดข้อผิดพลาด: {e}")

# ************************************* # 

** ข้อมูล Metadata (EXIF) **

ImageWidth               : 2448

ImageLength              : 3264

BitsPerSample            : (8, 8, 8)

GPSInfo                  : 870

ResolutionUnit           : 2

ExifOffset               : 252

Make                     : HUAWEI

Model                    : LDN-LX2

Software                 : LDN-LX2 8.0.0.163(C636)

DateTime                 : 2024:10:12 11:24:34

YCbCrPositioning         : 1

XResolution              : 72.0

YResolution              : 72.0


==================================================

** ข้อมูลพิกัดสำหรับ Google Maps **

Latitude (Decimal)  : 14.629546

Longitude (Decimal) : 101.409677

------------------------------

คัดลอกไปวางใน Google Maps: 14.629546, 101.409677

ลิงก์แผนที่: https://www.google.com/maps?q=14.629546,101.409677




# ************************************************************************#

Tag:Code Python,DMS,Google Maps,meta,ImageWidth,ImageLength,BitsPerSample,GPSInfo,

ResolutionUnit,ExifOffset,Make,Model,Software,DateTime,YCbCrPositioning,XResolution,YResolution


ความคิดเห็น