hMatoba / Piexif

Exif manipulation with pure python script.
MIT License
367 stars 81 forks source link

UnboundLocalError: local variable 'new_value' referenced before assignment #82

Open kannes opened 5 years ago

kannes commented 5 years ago

piexif-1.1.2

from PIL import Image
import piexif

im = Image.open("/tmp/test.jpg")

gps_dict = {
    piexif.GPSIFD.GPSLongitude: 1.1,
    piexif.GPSIFD.GPSLatitude: 2.1,
    piexif.GPSIFD.GPSAltitude: 3.1,
}
exif_dict = {'GPS': gps_dict}
exif_bytes = piexif.dump(exif_dict)
im.save("/tmp/test.exif.jpg", "jpeg", exif=exif_bytes)

errors as

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-116-b699857b7bb8> in <module>
      8 }
      9 exif_dict = {'GPS': gps_dict}
---> 10 exif_bytes = piexif.dump(exif_dict)
     11 im.save("/tmp/s/45_08034_lvl02-oblique-left.5.exif.jpg", "jpeg", exif=exif_bytes)

~/.local/lib/python3.7/site-packages/piexif/_dump.py in dump(exif_dict_original)
     72         exif_length = 0
     73     if gps_is:
---> 74         gps_set = _dict_to_bytes(gps_ifd, "GPS", zeroth_length + exif_length)
     75         gps_bytes = b"".join(gps_set)
     76         gps_length = len(gps_bytes)

~/.local/lib/python3.7/site-packages/piexif/_dump.py in _dict_to_bytes(ifd_dict, ifd, ifd_offset)
    335             length_str, value_str, four_bytes_over = _value_to_bytes(raw_value,
    336                                                                      value_type,
--> 337                                                                      offset)
    338         except ValueError:
    339             raise ValueError(

~/.local/lib/python3.7/site-packages/piexif/_dump.py in _value_to_bytes(raw_value, value_type, offset)
    245                                 struct.pack(">L", den))
    246         value_str = struct.pack(">I", offset)
--> 247         four_bytes_over = new_value
    248     elif value_type == TYPES.SRational:
    249         if isinstance(raw_value[0], numbers.Integral):

UnboundLocalError: local variable 'new_value' referenced before assignment
kannes commented 5 years ago

I get my code is broken, but the error it triggered is one (probably unrelated) in piexif code :)

mdonahoe commented 5 years ago

You can't use floats. The numbers for these fields are treated as Rationals, and need to either be integral or a (numerator, denominator) tuple.

Error is cryptic, I agree, because the if-elif chain doesn't have a else that raises a ValueError.

kannes commented 5 years ago

Ah, that makes sense. Thanks!

cekk commented 5 years ago

I have the same error with some gps coordinates like these:

{1: 'N', 2: ((44, 1), (30, 1), (2997, 100)), 3: 'E', 4: ((11, 1), (21, 1), (5991, 100)), 5: 0, 6: (324663, 12176), 12: 'K', 13: (3083, 4231), 16: 'T', 17: (406646, 1481), 23: 'T', 24: (406646, 1481), 31: '24/1'}

The problem is with '24/1' value. These coordinates are automatically created by a digital camera, so i can't handle them.

I think that the better thing should be fixing the code to handle an else statement that doesn't break anything..the problem is that i don't know what should be a safe default value for new_value.

An empty string should be ok?

Aazad23 commented 1 year ago

Use latlons in following formats ((degress, 1), (minutes, 1), (seconds, 10000))