james-see / iptcinfo3

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

IPTCInfo.save_as doesn't work if self._fobj is file object (works if it's a filepath only) #37

Closed cjbumgardner closed 10 months ago

cjbumgardner commented 2 years ago

Code Example:

f = open(imagepath,'rb')
info = IPTCInfo(f)
info.save_as("new_path.jpg")

Raises:

ValueError: seek of closed file

This may be the intended functionality, but it seems that functionality shouldn't change depending on the content initiating IPTCInfo. The ValueError is actually due to two uses of 'with' statements using smart_open on self._fobj (when it is a file object). The first at the end of IPTCInfo.__init__ would close the file object, so when smart_open is called in IPTCInfo.save_as it is already closed.

ValentinVoigt commented 2 years ago

I encountered the same problem trying to use io.BytesIO. I tried resetting _fobj before saving, but there are more issues like #30 and #36. Bute since save uses tempfile.mkstemp anyway, I copied my BytesIO to a tempfile.NamedTemporaryFile and let IPTCInfo handle it like this instead:

buf = io.BytesIO()
buf.write(...)  # add image data

with tempfile.NamedTemporaryFile() as src:
    src.write(buf.getvalue())

    iptcinfo = IPTCInfo(src.name)
    # change stuff...
    iptcinfo.save_as(src.name)

    src.seek(0)
    buf = io.BytesIO(src.read())
james-see commented 11 months ago

@cjbumgardner yeah I would adopt @ValentinVoigt approach and save to tempfile and then let IPTCInfo handle it. Why would you not start with a file in the first place? Id be happy to review any pull requests to add the functionality that would depend on the content initiating.

james-see commented 10 months ago

ok no response, closing.