Closed RalfPeter closed 10 months ago
Hi!
This is because Windows systems usually use the user's localized language rather than utf-8 encoding.
If you open a file with python's open()
function, it automatically guesses the encoding format of the filename. However, the underlying execution of pyexiv2 is C++ code, so it requires the user to actively specify the encoding format of the filename.
See: https://github.com/LeoHsiao1/pyexiv2/blob/master/docs/Tutorial.md#class-image
Another option, if you don't want to specify the encoding format of each image file, you can open the image file with python's open()
function and then parse the image with pyexiv2.ImageData
.
See: https://github.com/LeoHsiao1/pyexiv2/blob/master/docs/Tutorial.md#class-imagedata
Thank for your advice. I will post my favorite solution as soon as i found.
I made the following to solve my problem: i wrapped the the pyexiv2 functions into a class EExiv2, with init and a method save(), see code below:
class EExiv2:
def __init__(self, file: Union[str, Path], verbose=False):
self.file = Path(file).resolve()
if not self.file.is_file():
raise FileNotFoundError
self.verbose = verbose
# initialize image
try:
with open(self.file, 'rb') as f:
self.image = ImageData(f.read())
if self.image:
self.data_exif = self.read_exif()
self.data_iptc = self.read_iptc()
self.data_xmp = self.image.read_xmp()
self.comment = self.image.read_comment()
self.data_icc = self.image.read_icc()
self.data_thumbnail = self.image.read_thumbnail()
except TypeError as e:
if self.verbose:
print('EXIF_init', f"Error: {type(e).__name__} - {e.args}")
raise TypeError
def save(self, close=True):
if self.image:
self.image.modify_exif(self.data_exif)
self.image.modify_iptc(self.data_iptc)
self.image.modify_xmp(self.data_xmp)
if len(self.data_icc) > 0:
self.image.modify_icc(self.data_icc)
if len(self.comment) > 0:
self.image.modify_comment(self.comment)
if len(self.data_thumbnail) > 0:
self.image.modify_thumbnail(self.data_thumbnail)
try:
# Get the bytes data of the image and save it to the file
data = self.image.get_bytes()
with open(self.file, 'rb+') as f:
# Empty the original file
f.seek(0)
f.truncate()
f.write(data)
except FileNotFoundError:
print(f"File not found: {self.file}")
if close:
self.image.close()
Thank you for your advice.
Hi Leo, I just converted my (GoPro) project from piexif to your pyexiv2. It was easy and most without to much work. Ty for your work. Now i tried to open a file with name: "C:/photos/motorrad/münchen/20120701_101216.jpg'. The init of Image is encoding the filename with utf-8 and filename will not be found. If i encode myself then error is that bytes dont have a method encoding. I guess you had same problems with your mandarin filenames. Do you have a tip, how i can solve the problem? Why do you encode filename? All filenames in python (>2.9?) are already unicode. Ty for an answer