পাইথনে, আমি কীভাবে কোনও চিত্রের এক্সিফ ডেটা পড়ব?


131

আমি পিআইএল ব্যবহার করছি আমি কীভাবে EXIF ​​ডেটা স্টাফের অভিধানে রূপান্তর করব?


1
: এখানে উত্তর দেখুন stackoverflow.com/questions/765396/...
ডেভিড Wolever

yetoy.net/dev/pyexiv2/tutorial.html এটি সবচেয়ে সহজ এবং সর্বাধিক বিস্তৃত।
কুমার দীপক

এখানে আরো সাম্প্রতিক প্রশ্ন: stackoverflow.com/questions/14009148/exif-reading-library
অ্যান্টনি Hatchkins

উত্তর:


183

এটা চেষ্টা কর:

import PIL.Image
img = PIL.Image.open('img.jpg')
exif_data = img._getexif()

এটি আপনাকে এক্সআইএফ সংখ্যার ট্যাগ দ্বারা সূচকযুক্ত একটি অভিধান দেবে। আপনি যদি প্রকৃত এক্সআইএফ ট্যাগ নামের স্ট্রিং দ্বারা সূচিকৃত অভিধানটি চান তবে এর মতো কিছু চেষ্টা করুন:

import PIL.ExifTags
exif = {
    PIL.ExifTags.TAGS[k]: v
    for k, v in img._getexif().items()
    if k in PIL.ExifTags.TAGS
}

10
পাইথন 3 বিকল্প?
সন্তোষ কুমার

2
@ 2rs2ts: চেষ্টা করুন import ExifTags( PILউপসর্গ ছাড়া )
ফ্লোরিয়ান ব্রুকার

12
পাইথন 3 এর জন্য বালিশ ব্যবহার করুন। এটি পিআইএল-এর একটি কাঁটাচামচ, যা এখনও বিকশিত হচ্ছে, এবং এটি একটি অজগর 3 সামঞ্জস্যপূর্ণ সংস্করণ রয়েছে
Mzzl

1
আপনি কি এই প্রশ্নে এটি পরীক্ষা করতে পারেন, ছবিগুলি ডাউনলোড করতে এবং চিত্র বিবরণ পেতে চেষ্টা করতে পারেন? stackoverflow.com/questions/22173902/…
এজে

3
কেবল রেফারেন্সের জন্য এক্সিফ
আইমেজিং

30

আপনি এক্সিফ্রেড মডিউলটিও ব্যবহার করতে পারেন :

import exifread
# Open image file for reading (binary mode)
f = open(path_name, 'rb')

# Return Exif tags
tags = exifread.process_file(f)

1
আপনি কি এই প্রশ্নে এটি পরীক্ষা করতে পারেন, ছবিগুলি ডাউনলোড করতে এবং চিত্র বিবরণ পেতে চেষ্টা করতে পারেন? stackoverflow.com/questions/22173902/…
এজে

2
উভয় চিত্রের জন্য ক্লেটন, এক্সিফ্রেড খালি অভিধান প্রদান করে। তবে আমি আমার ফটোগুলিতে পরীক্ষা করেছি এবং এটি ঠিক কাজ করে।
tnq177

আমি কিছু সেট চিত্রের জন্য একটি খালি অভিধানও পাই। কেস কেন এই ঘটনাটি সম্পর্কে মন্তব্য করতে পারেন? এক্সিফ্রেড.প্রসেস_ফাইলে () কী ধরণের চিত্র নিয়ে কাজ করে?
মোমচিল

17

আমি এটি ব্যবহার:

import os,sys
from PIL import Image
from PIL.ExifTags import TAGS

for (k,v) in Image.open(sys.argv[1])._getexif().iteritems():
        print '%s = %s' % (TAGS.get(k), v)

বা একটি নির্দিষ্ট ক্ষেত্র পেতে:

def get_field (exif,field) :
  for (k,v) in exif.iteritems():
     if TAGS.get(k) == field:
        return v

exif = image._getexif()
print get_field(exif,'ExposureTime')

6
আরও ভাল, আপনি ট্যাগগুলি এর সাথে বিপরীত করতে পারেন name2tagnum = dict((name, num) for num, name in TAGS.iteritems())এবং তারপরেও করতে পারেন name2tagnum['ExposureTime']
বেন

7
পাইথন 3 জন্য, পরিবর্তন exif.iteritems()করার জন্যexif.items()
SPRBRN

14

পাইথন 3.x এবং শুরু করার জন্য Pillow==6.0.0, Imageঅবজেক্টগুলি এখন এমন একটি getexif()পদ্ধতি সরবরাহ করে যা প্রত্যাবর্তন করে <class 'PIL.Image.Exif'>বা Noneযদি চিত্রটিতে কোনও এক্সআইএফ ডেটা না থাকে।

থেকে বালিশ 6.0.0 রিলিজ নোট :

getexif()যোগ করা হয়েছে, যা একটি Exifউদাহরণ দেয় returns মানগুলি পুনরুদ্ধার করা যায় এবং অভিধানের মতো সেট করা যায়। জেপিইজি, পিএনজি বা ডাব্লুইইবিপি সংরক্ষণ exifকরার সময়, আউটপুট চিত্রের যে কোনও পরিবর্তন অন্তর্ভুক্ত করার জন্য উদাহরণটি আর্গুমেন্ট হিসাবে পাস করা যেতে পারে ।

Exifআউটপুট কেবল একটি থেকে casted যাবে dict, যাতে এক্জিফ তথ্য তারপর একটি নিয়মিত কী-মান জোড়া হিসাবে অ্যাক্সেস করা যেতে পারে dict। কীগুলি হ'ল 16-বিট পূর্ণসংখ্যা যা ExifTags.TAGSমডিউলটি ব্যবহার করে তাদের স্ট্রিংয়ের নামের সাথে ম্যাপ করা যায় ।

from PIL import Image, ExifTags

img = Image.open("sample.jpg")
img_exif = img.getexif()
print(type(img_exif))
# <class 'PIL.Image.Exif'>

if img_exif is None:
    print("Sorry, image has no exif data.")
else:
    img_exif_dict = dict(img_exif)
    print(img_exif_dict)
    # { ... 42035: 'FUJIFILM', 42036: 'XF23mmF2 R WR', 42037: '75A14188' ... }
    for key, val in img_exif_dict.items():
        if key in ExifTags.TAGS:
            print(f"{ExifTags.TAGS[key]}:{repr(val)}")
            # ExifVersion:b'0230'
            # ...
            # FocalLength:(2300, 100)
            # ColorSpace:1
            # FocalLengthIn35mmFilm:35
            # ...
            # Model:'X-T2'
            # Make:'FUJIFILM'
            # ...
            # DateTime:'2019:12:01 21:30:07'
            # ...

পাইথন 3.6.8 এবং Pillow==6.0.0


এটি আমার পক্ষে কাজ করে না, আমি বাইনারিটিতে .info পদ্ধতি ব্যবহার করে কেবল এক্সিফ ডেটা দেখতে পারি
জিএম

12
import sys
import PIL
import PIL.Image as PILimage
from PIL import ImageDraw, ImageFont, ImageEnhance
from PIL.ExifTags import TAGS, GPSTAGS



class Worker(object):
    def __init__(self, img):
        self.img = img
        self.exif_data = self.get_exif_data()
        self.lat = self.get_lat()
        self.lon = self.get_lon()
        self.date =self.get_date_time()
        super(Worker, self).__init__()

    @staticmethod
    def get_if_exist(data, key):
        if key in data:
            return data[key]
        return None

    @staticmethod
    def convert_to_degress(value):
        """Helper function to convert the GPS coordinates
        stored in the EXIF to degress in float format"""
        d0 = value[0][0]
        d1 = value[0][1]
        d = float(d0) / float(d1)
        m0 = value[1][0]
        m1 = value[1][1]
        m = float(m0) / float(m1)

        s0 = value[2][0]
        s1 = value[2][1]
        s = float(s0) / float(s1)

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

    def get_exif_data(self):
        """Returns a dictionary from the exif data of an PIL Image item. Also
        converts the GPS Tags"""
        exif_data = {}
        info = self.img._getexif()
        if info:
            for tag, value in info.items():
                decoded = TAGS.get(tag, tag)
                if decoded == "GPSInfo":
                    gps_data = {}
                    for t in value:
                        sub_decoded = GPSTAGS.get(t, t)
                        gps_data[sub_decoded] = value[t]

                    exif_data[decoded] = gps_data
                else:
                    exif_data[decoded] = value
        return exif_data

    def get_lat(self):
        """Returns the latitude and longitude, if available, from the 
        provided exif_data (obtained through get_exif_data above)"""
        # print(exif_data)
        if 'GPSInfo' in self.exif_data:
            gps_info = self.exif_data["GPSInfo"]
            gps_latitude = self.get_if_exist(gps_info, "GPSLatitude")
            gps_latitude_ref = self.get_if_exist(gps_info, 'GPSLatitudeRef')
            if gps_latitude and gps_latitude_ref:
                lat = self.convert_to_degress(gps_latitude)
                if gps_latitude_ref != "N":
                    lat = 0 - lat
                lat = str(f"{lat:.{5}f}")
                return lat
        else:
            return None

    def get_lon(self):
        """Returns the latitude and longitude, if available, from the 
        provided exif_data (obtained through get_exif_data above)"""
        # print(exif_data)
        if 'GPSInfo' in self.exif_data:
            gps_info = self.exif_data["GPSInfo"]
            gps_longitude = self.get_if_exist(gps_info, 'GPSLongitude')
            gps_longitude_ref = self.get_if_exist(gps_info, 'GPSLongitudeRef')
            if gps_longitude and gps_longitude_ref:
                lon = self.convert_to_degress(gps_longitude)
                if gps_longitude_ref != "E":
                    lon = 0 - lon
                lon = str(f"{lon:.{5}f}")
                return lon
        else:
            return None

    def get_date_time(self):
        if 'DateTime' in self.exif_data:
            date_and_time = self.exif_data['DateTime']
            return date_and_time 

if __name__ == '__main__':
    try:
        img = PILimage.open(sys.argv[1])
        image = Worker(img)
        lat = image.lat
        lon = image.lon
        date = image.date
        print(date, lat, lon)

    except Exception as e:
        print(e)

8

আমি খুঁজে পেয়েছি যে ._getexifউচ্চতর অজগর সংস্করণে ব্যবহার করা কাজ করে না, তদুপরি, এটি একটি সুরক্ষিত শ্রেণি এবং যদি সম্ভব হয় তবে এটি ব্যবহার করা উচিত। ডিবাগারের চারপাশে খনন করার পরে এটিই আমি একটি চিত্রের জন্য এক্সআইএফ ডেটা পাওয়ার সর্বোত্তম উপায় বলে মনে করি:

from PIL import Image

def get_exif(path):
    return Image.open(path).info['parsed_exif']

এটি একটি চিত্রের সমস্ত এক্সআইএফ ডেটার একটি অভিধান প্রদান করে।

দ্রষ্টব্য: পাইথন 3.x এর জন্য পিআইএল এর পরিবর্তে বালিশ ব্যবহার করুন


2
info['parsed_exif']বালিশ 6.0 বা আরও নতুন প্রয়োজন। info['exif']5.4 এ উপলব্ধ তবে এটি একটি কাঁচা বাইস্টেরিং।
mসমান্ড

1
সেখানে নেই info['parsed_exif']সংস্করণ 7.0.0 মধ্যে; শুধুমাত্র info['exif']
ZF007

7

এখানে পড়া যা পড়া সহজ হতে পারে। আশা করি এটি সহায়ক।

from PIL import Image
from PIL import ExifTags

exifData = {}
img = Image.open(picture.jpg)
exifDataRaw = img._getexif()
for tag, value in exifDataRaw.items():
    decodedTag = ExifTags.TAGS.get(tag, tag)
    exifData[decodedTag] = value

0

আমি সাধারণত জেপিজি ফাইলে এক্সিফ তথ্য সেট করার জন্য পাইক্সিভি 2 ব্যবহার করি তবে আমি যখন কোনও স্ক্রিপ্ট QGIS স্ক্রিপ্ট ক্র্যাশে লাইব্রেরিটি আমদানি করি।

আমি লাইব্রেরি এক্সিফ ব্যবহার করে একটি সমাধান পেয়েছি:

https://pypi.org/project/exif/

এটি ব্যবহার করা এত সহজ, এবং কিউগিসের সাথে আমি ডোন করি না, কোনও সমস্যা নেই।

এই কোডটিতে আমি জিপিএসের স্থানাঙ্কগুলি স্ক্রিনের স্ন্যাপশটে sertোকান:

from exif import Image
with open(file_name, 'rb') as image_file:
    my_image = Image(image_file)

my_image.make = "Python"
my_image.gps_latitude_ref=exif_lat_ref
my_image.gps_latitude=exif_lat
my_image.gps_longitude_ref= exif_lon_ref
my_image.gps_longitude= exif_lon

with open(file_name, 'wb') as new_image_file:
    new_image_file.write(my_image.get_file())
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.