Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata support #56

Merged
merged 4 commits into from
Sep 13, 2012
Merged

Metadata support #56

merged 4 commits into from
Sep 13, 2012

Conversation

wronglink
Copy link
Contributor

Added dict-like metadata property to Image class. It allows to iterate metadata properties and get their values.

At first I wanted to make a normal dict-like object (with setting and deleting metadata header options). But unfortunately ImageMagick doesn't support writing of image properties to file. So it sets and deletes options, but it doesn't save any changes to metadata (even if image is saved to a new file).

Here are some usage examples:

>>> img = Image(filename='/Users/wronglink/Src/wand/wandtests/assets/beach.jpg')
>>> #count metadata headers
>>> len(img.metadata)
52
>>> #get list of available metadata headers
>>> list(img.metadata)
['date:create', 'date:modify', 'exif:ApertureValue', 'exif:ColorSpace',
 'exif:ComponentsConfiguration', 'exif:CompressedBitsPerPixel',
 'exif:Compression', 'exif:CustomRendered', 'exif:DateTime',
 'exif:DateTimeDigitized', 'exif:DateTimeOriginal', 'exif:DigitalZoomRatio',
 'exif:ExifImageLength', 'exif:ExifImageWidth', 'exif:ExifOffset',
 'exif:ExifVersion', 'exif:ExposureBiasValue', 'exif:ExposureMode',
 'exif:ExposureTime', 'exif:FileSource', 'exif:Flash', 'exif:FlashPixVersion',
 'exif:FNumber', 'exif:FocalLength', 'exif:FocalPlaneResolutionUnit',
 'exif:FocalPlaneXResolution', 'exif:FocalPlaneYResolution',
 'exif:InteroperabilityIndex', 'exif:InteroperabilityOffset',
 'exif:InteroperabilityVersion', 'exif:ISOSpeedRatings',
 'exif:JPEGInterchangeFormat', 'exif:JPEGInterchangeFormatLength', 'exif:Make',
 'exif:MakerNote', 'exif:MaxApertureValue', 'exif:MeteringMode', 'exif:Model',
 'exif:Orientation', 'exif:RelatedImageLength', 'exif:RelatedImageWidth',
 'exif:ResolutionUnit', 'exif:SceneCaptureType', 'exif:SensingMethod',
 'exif:ShutterSpeedValue', 'exif:UserComment', 'exif:WhiteBalance',
 'exif:XResolution', 'exif:YCbCrPositioning', 'exif:YResolution',
 'jpeg:colorspace', 'jpeg:sampling-factor']
>>> #work with specific headers
>>> 'exif:ApertureValue' in img.metadata
True
>>> 'exif:UnknownValue' in img.metadata
False
>>> img.metadata.get('exif:ApertureValue')
'192/32'
>>> img.metadata.get('exif:UnknownValue', "I don't know")
"I don't know"
>>> #iterate all metadata values
>>> for i in img.metadata.keys():
...     print i + ": " + img.metadata[i]
...     
... 
date:create: 2012-08-14T12:58:35+06:00
date:modify: 2012-08-14T12:58:35+06:00
exif:ApertureValue: 192/32
exif:ColorSpace: 1
exif:ComponentsConfiguration: 1, 2, 3, 0
exif:CompressedBitsPerPixel: 2/1
exif:Compression: 6
exif:CustomRendered: 0
exif:DateTime: 2012:05:08 12:11:35
exif:DateTimeDigitized: 2011:03:11 11:52:47
exif:DateTimeOriginal: 2011:03:11 11:52:47
exif:DigitalZoomRatio: 3072/3072
exif:ExifImageLength: 600
exif:ExifImageWidth: 800
exif:ExifOffset: 186
exif:ExifVersion: 48, 50, 50, 48
exif:ExposureBiasValue: 0/3
exif:ExposureMode: 0
exif:ExposureTime: 1/400
exif:FileSource: 3
exif:Flash: 24
exif:FlashPixVersion: 48, 49, 48, 48
exif:FNumber: 80/10
exif:FocalLength: 5800/1000
exif:FocalPlaneResolutionUnit: 2
exif:FocalPlaneXResolution: 3072000/225
exif:FocalPlaneYResolution: 2304000/169
exif:InteroperabilityIndex: R98
exif:InteroperabilityOffset: 3338
exif:InteroperabilityVersion: 48, 49, 48, 48
exif:ISOSpeedRatings: 80
exif:JPEGInterchangeFormat: 3486
exif:JPEGInterchangeFormatLength: 4896
exif:Make: Canon
exif:MakerNote: 26, 0, 1, 0, 3, 0, 46, 0, 0, 0, 230,
                # ... other values ...
                4, 0, 9, 0,
exif:MaxApertureValue: 95/32
exif:MeteringMode: 5
exif:Model: Canon PowerShot SD750
exif:Orientation: 1
exif:RelatedImageLength: 3072
exif:RelatedImageWidth: 2304
exif:ResolutionUnit: 2
exif:SceneCaptureType: 0
exif:SensingMethod: 2
exif:ShutterSpeedValue: 277/32
exif:UserComment: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                  # ... other values ...
                  0, 0, 0, 0, 0, 0, 0
exif:WhiteBalance: 0
exif:XResolution: 72/1
exif:YCbCrPositioning: 1
exif:YResolution: 72/1
jpeg:colorspace: 2
jpeg:sampling-factor: 2x2,1x1,1x1

Added dict-like `metadata` property to `Image` class. It allows to iterate
metadata properties and get their values.
@wronglink
Copy link
Contributor Author

By the way, it also covers #25

@dahlia
Copy link
Collaborator

dahlia commented Sep 13, 2012

Oops, the build has failed. Travis CI recently works strangely.

@@ -1421,10 +1422,54 @@ def clone(self):
"""
return type(self)(iterator=self)

import UserDict
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don’t use this now, right? It seems to has to be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O_o Don't know where did it came here from. Removed this unnecessary import.

@dahlia
Copy link
Collaborator

dahlia commented Sep 13, 2012

Hey @huntrax11, here’s what you’ve been looking for.

@wronglink
Copy link
Contributor Author

Oops, the build has failed. Travis CI recently works strangely.

Yeah, but it failed on Attest lib installation. It even haven't run the code :-)

install: 'pip install Attest' returned false.
Done. Build script exited with: 1

@@ -460,6 +460,7 @@ def __init__(self, image=None, blob=None, file=None, filename=None,
read = True
if not read:
raise TypeError('invalid argument(s)')
self.metadata = Metadata(self)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be documented. You can define an empty attribute at class-level e.g.:

#: (:class:`Metadata`) The metadata mapping of the image.  Read only.
metadata = None

Anyway how does it works well, even though there is no 'metadata' in the __slots__ list?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway how does it works well, even though there is no 'metadata' in the slots list?

Yes, but I'l add it's class-level definition, as you wrote before.

dahlia added a commit that referenced this pull request Sep 13, 2012
@dahlia dahlia merged commit c95236f into emcconville:master Sep 13, 2012
@dahlia
Copy link
Collaborator

dahlia commented Sep 13, 2012

Okay, I merged it and it will be included to 0.3.0 release.

@wronglink
Copy link
Contributor Author

Cool thanks.

dahlia added a commit that referenced this pull request Sep 13, 2012
dahlia added a commit that referenced this pull request Sep 13, 2012
dahlia added a commit that referenced this pull request Sep 13, 2012
dahlia added a commit that referenced this pull request Sep 13, 2012
@dahlia dahlia mentioned this pull request Mar 11, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants