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

@wronglink wronglink commented Sep 13, 2012

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
wronglink added 2 commits Sep 13, 2012
Added dict-like `metadata` property to `Image` class. It allows to iterate
metadata properties and get their values.
@wronglink
Copy link
Contributor Author

@wronglink wronglink commented Sep 13, 2012

By the way, it also covers #25

@dahlia
Copy link
Collaborator

@dahlia 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

@dahlia dahlia Sep 13, 2012

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

Copy link
Contributor Author

@wronglink wronglink Sep 13, 2012

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

@dahlia
Copy link
Collaborator

@dahlia dahlia commented Sep 13, 2012

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

@wronglink
Copy link
Contributor Author

@wronglink wronglink commented Sep 13, 2012

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

@dahlia dahlia Sep 13, 2012

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

@wronglink wronglink Sep 13, 2012

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 issue Sep 13, 2012
@dahlia dahlia merged commit c95236f into emcconville:master Sep 13, 2012
1 check passed
@dahlia
Copy link
Collaborator

@dahlia dahlia commented Sep 13, 2012

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

@wronglink
Copy link
Contributor Author

@wronglink wronglink commented Sep 13, 2012

Cool thanks.

dahlia added a commit that referenced this issue Sep 13, 2012
dahlia added a commit that referenced this issue Sep 13, 2012
dahlia added a commit that referenced this issue Sep 13, 2012
dahlia added a commit that referenced this issue 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
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants