Add support for loading image streams

Bug #518732 reported by Mark Lee
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
pyexiv2
Fix Released
Wishlist
Olivier Tilloy

Bug Description

Currently, pyexiv2 (both 0.1.x and 0.2~bzr) only support loading images from the filesystem. I have added basic support for loading "image streams" via file-like objects (i.e., objects with the "read()" method), including unit tests.

This enhancement depends on bug 517298.

Olivier Tilloy (osomon)
Changed in pyexiv2:
assignee: nobody → Mark Lee (malept)
importance: Undecided → Wishlist
status: New → Confirmed
status: Confirmed → In Progress
Revision history for this message
Olivier Tilloy (osomon) wrote :

Hey Mark, thanks for your work on this one.
I didn't test it but I read the code, and it looks correct to me.

Supporting file-like objects sounds neat, but I was wondering what's the most common use-case, and it occurred to me that in general image manipulation libraries rather give you access to a data buffer than to a file-like interface. See for example PIL.Image, and its tostring() method (http://www.pythonware.com/library/pil/handbook/image.htm#Image.tostring). Anyway, I think this use-case ought to be considered, at least as seriously as supporting file-like objects.

If we are to support different "constructors" for ImageMetadata, I would rather go for static methods than a polymorphic constructor (which implies magic code and is harder to document), e.g.:

  ImageMetadata.open(filename_or_file)
  ImageMetadata.from_buffer(data)

If .open() (or .__init__()) is called with a file-like object, the file can be .read() from the python code and the data passed directly to .from_buffer(), which avoids the need for a tricky data stream constructor in C++.

I'm open to comments, critics and suggestions. Let's agree on the API before implementing it.

Revision history for this message
Mark Lee (malept) wrote :

My particular use case is retrieving metadata from an uploaded image file in a web application. In Django, at least, the default settings are that smaller files (for some definition of "smaller") are handled in-memory, whereas larger files are handled on disk (see <http://docs.djangoproject.com/en/dev/topics/http/file-uploads/#upload-handlers>). Because the upload handlers are customizable, Django provides convenient access to uploaded files via file-like objects.

If I recall correctly, when I was writing my implementation, I was initially thinking about static methods, but I thought that at least in C++, overloading the constructor felt more natural to the language (whatever the analogous term to "pythonic" is).

I don't have any objections to using @staticmethod-style constructors in the Python code.

Revision history for this message
Olivier Tilloy (osomon) wrote :

I linked a branch (lp:~osomon/pyexiv2/from_buffer) that implements instantiating an ImageMetadata from a buffer, and exposing the image data as a buffer. This also allows to easily instantiate an ImageMetadata from a file-like object, using the following syntax:

    m = ImageMetadata.from_buffer(f.read())

@Mark and others, your feedback and comments on this approach are welcome, if it suits your needs I'll merge it.

Olivier Tilloy (osomon)
Changed in pyexiv2:
assignee: Mark Lee (malept) → Olivier Tilloy (osomon)
milestone: none → 0.2
Revision history for this message
Olivier Tilloy (osomon) wrote :

In the absence of feedback, I assume the proposed solution is good enough.
Merged with revision 288.

Changed in pyexiv2:
status: In Progress → Fix Committed
Olivier Tilloy (osomon)
Changed in pyexiv2:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.