james-see / iptcinfo3

iptcinfo working for python 3 finally do pip3 install iptcinfo3
51 stars 31 forks source link

Can't save files #26

Open martimpassos opened 3 years ago

martimpassos commented 3 years ago

I'm trying to write metadata from a Pandas dataframe to jpg images:

for i, file in enumerate(files):
    if file.endswith(".jpg"):
        basename = os.path.split(file)[1]
        name = basename.split(".")[0]
        print(name)
        info = IPTCInfo(file, force=True)
        # info["reference number"] = df.loc[name, "dcterms:identifier"]
        info["credit"] = df.loc[name, "dcterms:creator"]
        info["object name"] = df.loc[name, "dcterms:title"]
        info["caption/abstract"] = df.loc[name, "dcterms:description"]
        info["image type"] = df.loc[name, "dcterms:type"]
        # info["image orientation"] = f"{df.loc[name, "schema:width"]}cm x {df.loc[name, "schema:height"]}cm"
        info["keywords"] = list(df.loc[name, "foaf:depicts"].split("||"))
        info["release date"] = df.loc[name, "dcterms:date"]
        info["release time"] = df.loc[name, "dcterms:temporal"]
        info["country/primary location name"] = "Brazil"
        info["province/state"] = "RJ"
        info["city"] = "Rio de Janeiro"
        info["custom1"] = str(df.loc[name, "latitude"]) + "S"
        info["custom2"] = str(df.loc[name, "longitude"]) + "W"
        info["copyright notice"] = "This image is in the Public Domain"
        info.save_as(f"home/jpeg-hd/tagged/{basename}")
        print(f"Tagged image {i+1} of {len(files)}")
    else:
        continue

but I'm getting this error:

WARNING: problems with charset recognition (b'\x1b')
Traceback (most recent call last):
  File "modules/iptc.py", line 36, in <module>
    info.save_as(basename)
  File "/usr/local/lib/python3.8/site-packages/iptcinfo3.py", line 670, in save_as
    data = self.photoshopIIMBlock(adobe, self.packedIIMData())
  File "/usr/local/lib/python3.8/site-packages/iptcinfo3.py", line 892, in packedIIMData
    if len(value) == 0:
TypeError: object of type 'float' has no len()

Am I doing something wrong? save() also does not seem to work. The images do not have prior IPTC tags (hence the force=True flag).

james-see commented 3 years ago

@martimpassos can you provide the example image? I will test on my end and show you how to save properly.

james-see commented 3 years ago

@martimpassos that error implies that at least one of the fields you are setting should be a list type vs. a single value float or string. I was tripped up by this too before. Try adding [ ] around each of the values on the right side of the equals for custom1 and custom2 and it should work fine.

martimpassos commented 3 years ago

@jamesacampbell thanks for the feedback. After some debugging I figured it was breaking on nan values, so after replacing those with empty strings it ran succesfully. However some fields are acting a bit weird: custom1 and custom2 appear as

Object Preview File Format      : Unknown (-22.965818S)
Object Preview File Version     : -43.226557W

and image orientation also writes as Unknown (value). I tried wrapping them in [ ] without success. Info is coming from exiftool.

james-see commented 3 years ago

@martimpassos you have to .append I believe just like a list. Can you try that instead of = ?

james-see commented 3 years ago

see the example from the readme: Lists for keywords, so you can just append! info['keywords'].append('cool')

gregsomm commented 3 years ago

I'm also running into a problem. For a test, I'm simply loading a JPEG, then writing it back out. I get these errors:

packedIIMData: illegal dataname '183' (183) packedIIMData: illegal dataname '240' (240)

Here's the code:

from iptcinfo3 import IPTCInfo

info = IPTCInfo('image7tagged.jpeg', force=True)
info.save_as('taggedbyiptcinfo3.jpg')

Any idea of what's causing this?

james-see commented 3 years ago

@martimpassos any follow up on this re: trying append ?

james-see commented 3 years ago

@gregsomm those are warnings correct? My guess is when writing the data back out there are chars / encodings it does not like. I would try to wrap in string or int.

gregsomm commented 3 years ago

Thanks for responding. I assume the warnings are correct, but literally, all I do is load the image and then try to save it into a new file - those two lines of code are my entire test. Is there something I can do between the load and the save in order to repair those problems?

martimpassos commented 3 years ago

@jamesacampbell sorry for my delayed response. I ended up adopting pyexiftool since it gives me the ability to write GPS tags too, which are of interest to my project. However, working in a cultural institution I can assure that support for IPTC Extension 1.5 fields would be really great. I'm not super happy with pyexiftool since I have to explicitly declare the Exiftool executable's path and this complicates usage inside Docker containers for instance.

james-see commented 3 years ago

@gregsomm I would need the exact image you are trying so I can run it myself to confirm and get to root cause for you. Standing by and I will be happy to troubleshoot it.

I would try the following:

info = IPTCInfo('image7tagged.jpeg', force=True, inp_charset='utf8', out_charset='utf8')
james-see commented 3 years ago

@martimpassos I understand and appreciate the explanation. If you have time I would love help with this and I would review and approve any Pull Request that seems reasonable as I have done in the past. Also, if the cultural institution would sponsor this package I can devote some resources to updating it properly 💯 .