LeoHsiao1 / pyexiv2

Read and write image metadata, including EXIF, IPTC, XMP, ICC Profile.
GNU General Public License v3.0
196 stars 39 forks source link

set the 'Rating' tag , then the Exif Value conflict with the Xmp Value. #106

Closed 668168 closed 1 year ago

668168 commented 1 year ago

Step1. I set the Rating tag to 5 by Win Explorerer Windows10. and Read the Value by pyexiv2.

image

ia = pyexiv2.Image('imatest-examples-main\SFR\SFR_ISO12233-2000_EOS10D.jpg')
ia.read_exif()
ia.read_xmp()

Result:

 'Exif.Image.Rating': '5',
 'Exif.Image.RatingPercent': '99',
 'Xmp.MicrosoftPhoto.Rating': '99',
 'Xmp.xmp.Rating': '5',

Step2. I set the Rating tag to '2' by pyexiv2, But do not work.

ia.modify_exif({ 'Exif.Image.Rating': '2'})
ia.modify_exif({ 'Exif.Image.RatingPercent': '25'})

The Windows Explorer Show Rating = 2. image

The pyexiv2 read result Exif Value 2 conflict with the Xmp Value 5.

ia.read_xmp()
ia.read_exif()
 'Xmp.MicrosoftPhoto.Rating': '99',
 'Xmp.xmp.Rating': '5',
 'Exif.Image.Rating': '2',
 'Exif.Image.RatingPercent': '25',

Step3. both set the xmp exif Rating = 5. The Win Explorer still show Value 2.

image

 'Xmp.xmp.Rating': '5',
 'Xmp.xmp.RatingPercent': '99',
 'Exif.Image.Rating': '5',
 'Exif.Image.RatingPercent': '99',

SFR_ISO12233-2000_EOS10D.zip

LeoHsiao1 commented 1 year ago

Hello! EXIF, IPTC, and XMP are different image metadata standards. What kind of metadata does Windows use for rating? Let's give it a try.

First, prepare a image and erase all metadata:

import pyexiv2
img = pyexiv2.Image('1.jpg')
img.clear_exif()
img.clear_iptc()
img.clear_xmp()
img.close()

Then, open the file properties window and rate it: image

Finally, let's read the image metadata:

>>> img = pyexiv2.Image('1.jpg')
>>> img.read_exif()
{'Exif.Image.Rating': '5', 'Exif.Image.RatingPercent': '99', 'Exif.Image.ExifTag': '2122', 'Exif.Photo.0xea1c': '28 234 0 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...}
>>> img.read_xmp()
{'Xmp.xmp.Rating': '5', 'Xmp.MicrosoftPhoto.Rating': '99', 'Xmp.xmpMM.InstanceID': 'uuid:faf5bdd5-ba3d-11da-ad31'}

The conclusion is that Windows rating are saved as multiple image metadata. So we need to modify them together:

>>> img.modify_exif({'Exif.Image.Rating': '1', 'Exif.Image.RatingPercent': '10'})
>>> img.modify_xmp({'Xmp.xmp.Rating': '1', 'Xmp.MicrosoftPhoto.Rating': '10'})
668168 commented 1 year ago

Thanks for you replay @LeoHsiao1 .

I am agree with your conclusion, But refer to my step3, even so we modify them together from 5 to 1, but the Rating is still 5 in WIN explorer .

LeoHsiao1 commented 1 year ago

I have successfully modified the rating on your image. image

668168 commented 1 year ago

Thanks Leo,

By the Blew Code Test, I Think The Root Cause:

  1. Write. ONLY the 'Xmp.MicrosoftPhoto.Rating' range(0-100), Can effect the Explorer Rating Value.
  2. Read. set the Rating Value by Explorer, will effect all the *.Rating Value.

Thanks very much for your kindly help, even so it is not a pyexiv2 issue.

import os
import pyexiv2

ia = pyexiv2.Image('imatest-examples-main\SFR\SFR_ISO12233-2000_EOS10D.jpg')

print("\nSTEP0. Modify the Rating to 5 by Explorer Mannual")
print(f"ia.read_exif()['Exif.Image.Rating'] :\t {ia.read_exif()['Exif.Image.Rating']}")
print(f"ia.read_xmp()['Xmp.xmp.Rating'] :\t {ia.read_xmp()['Xmp.xmp.Rating']} ")
print(f"ia.read_xmp()['Xmp.MicrosoftPhoto.Rating'] :\t {ia.read_xmp()['Xmp.MicrosoftPhoto.Rating']} ")

print("\nSTEP1. Modify the Rating to 1 by pyexiv2") # it works.
ia.modify_xmp({'Xmp.xmp.Rating': 1, 'Xmp.MicrosoftPhoto.Rating':10})
print(f"ia.read_exif()['Exif.Image.Rating'] :\t {ia.read_exif()['Exif.Image.Rating']}")
print(f"ia.read_xmp()['Xmp.xmp.Rating'] :\t {ia.read_xmp()['Xmp.xmp.Rating']} ")
print(f"ia.read_xmp()['Xmp.MicrosoftPhoto.Rating'] :\t {ia.read_xmp()['Xmp.MicrosoftPhoto.Rating']} ")

print("\nSTEP2. Modify the Rating to 2 by pyexiv2") 
#ia.modify_xmp({'Xmp.xmp.Rating': 2, 'Xmp.MicrosoftPhoto.Rating':25})
ia.modify_xmp({'Xmp.xmp.Rating': 2, 'Xmp.MicrosoftPhoto.Rating':25})
print(f"ia.read_exif()['Exif.Image.Rating'] :\t {ia.read_exif()['Exif.Image.Rating']}")
print(f"ia.read_xmp()['Xmp.xmp.Rating'] :\t {ia.read_xmp()['Xmp.xmp.Rating']} ")
print(f"ia.read_xmp()['Xmp.MicrosoftPhoto.Rating'] :\t {ia.read_xmp()['Xmp.MicrosoftPhoto.Rating']} ")

print("\nSTEP3. !JUST! Modify the Xmp.MicrosoftPhoto.Rating to 50 by pyexiv2") 
#ia.modify_xmp({'Xmp.xmp.Rating': 3, 'Xmp.MicrosoftPhoto.Rating':50})
ia.modify_xmp({'Xmp.MicrosoftPhoto.Rating':50})
print(f"ia.read_exif()['Exif.Image.Rating'] :\t {ia.read_exif()['Exif.Image.Rating']}")
print(f"ia.read_xmp()['Xmp.xmp.Rating'] :\t {ia.read_xmp()['Xmp.xmp.Rating']} ")
print(f"ia.read_xmp()['Xmp.MicrosoftPhoto.Rating'] :\t {ia.read_xmp()['Xmp.MicrosoftPhoto.Rating']} ")

print("\nSTEP4. !JUST! Modify the Xmp.MicrosoftPhoto.Rating to 75 by pyexiv2") 
#ia.modify_xmp({'Xmp.xmp.Rating': 3, 'Xmp.MicrosoftPhoto.Rating':50})
ia.modify_xmp({'Xmp.MicrosoftPhoto.Rating':75})
print(f"ia.read_exif()['Exif.Image.Rating'] :\t {ia.read_exif()['Exif.Image.Rating']}")
print(f"ia.read_xmp()['Xmp.xmp.Rating'] :\t {ia.read_xmp()['Xmp.xmp.Rating']} ")
print(f"ia.read_xmp()['Xmp.MicrosoftPhoto.Rating'] :\t {ia.read_xmp()['Xmp.MicrosoftPhoto.Rating']} ")

print("\nSTEP5. !JUST! Modify the Xmp.MicrosoftPhoto.Rating to 99 by pyexiv2") 
#ia.modify_xmp({'Xmp.xmp.Rating': 5, 'Xmp.MicrosoftPhoto.Rating':99})
ia.modify_xmp({'Xmp.MicrosoftPhoto.Rating':99})
print(f"ia.read_exif()['Exif.Image.Rating'] :\t {ia.read_exif()['Exif.Image.Rating']}")
print(f"ia.read_xmp()['Xmp.xmp.Rating'] :\t {ia.read_xmp()['Xmp.xmp.Rating']} ")
print(f"ia.read_xmp()['Xmp.MicrosoftPhoto.Rating'] :\t {ia.read_xmp()['Xmp.MicrosoftPhoto.Rating']} ")
LeoHsiao1 commented 1 year ago

Thanks for testing, it may help others who see this issue.