xmp 0.2.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.tool-versions +1 -0
- data/.travis.yml +7 -0
- data/README.md +81 -0
- data/Rakefile +0 -1
- data/lib/xmp/convenience.rb +38 -0
- data/lib/xmp/document.rb +24 -0
- data/lib/xmp/error.rb +4 -0
- data/lib/xmp/handler/exifr.rb +22 -0
- data/lib/xmp/handler/file.rb +21 -0
- data/lib/xmp/handler/xml.rb +10 -0
- data/lib/xmp/handler.rb +23 -0
- data/lib/xmp/namespace.rb +39 -56
- data/lib/xmp/version.rb +2 -2
- data/lib/xmp.rb +20 -70
- data/spec/exifr_jpeg_spec.rb +15 -5
- data/spec/exifr_tiff_spec.rb +17 -0
- data/spec/fixtures/UPPERCASE.JPG +0 -0
- data/spec/fixtures/multiple-app1.tiff +0 -0
- data/spec/fixtures/xmp.xml +1 -0
- data/spec/fixtures/xmp3.xml +62 -0
- data/spec/fixtures/xmp4.xml +66 -0
- data/spec/fixtures/xmp5.xml +63 -0
- data/spec/spec_helper.rb +3 -7
- data/spec/xmp_spec.rb +68 -1
- data/xmp.gemspec +11 -8
- metadata +105 -40
- data/.rvmrc +0 -34
- data/README.rdoc +0 -53
- data/lib/xmp/silencer.rb +0 -11
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c71a383ba25e007195a1624a2d88311911d86323d6cb43d7107651904f91ec6f
|
4
|
+
data.tar.gz: f5d04040dd4905d29c7105d6aa20c3bf72b1feb8fad9ef93a719eacaece2f55b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1a4e7a6ff1563cf64298439ce866a8bf56fa4991d234f1e9b0c13859d87121d3eaf57d4bdf444ab4cd93e9a5d3be5ed935a5cde5381b43f1375f12abf42b74f4
|
7
|
+
data.tar.gz: 89d8d8e67dff63d882af773ce3053012deb25e4d92eb1a8645c1a2ba312a60a75b719499adfdb3667c0d258f6418ce067e7cef37ffba719dea07bf16e2b9d247
|
data/.gitignore
CHANGED
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 3.3.5
|
data/.travis.yml
ADDED
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# xmp - Extensible Metadata Platform (XMP) parser
|
2
|
+
|
3
|
+
XMP provides an object oriented interface to [XMP data](http://en.wikipedia.org/wiki/Extensible_Metadata_Platform). XMP data can be found in PDF, JPEG, GIF, PNG, and many other formats.
|
4
|
+
|
5
|
+
## Supported Formats
|
6
|
+
|
7
|
+
Format | File extension | Additional dependency
|
8
|
+
----------|-----------------|-----------------------
|
9
|
+
JPEG | .jpeg, .jpg | [exifr/jpeg](https://github.com/remvee/exifr)
|
10
|
+
TIFF | .tiff, .tif | [exifr/tiff](https://github.com/remvee/exifr)
|
11
|
+
XMP Files | .xmp, .xml | none
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
``` ruby
|
16
|
+
require 'xmp'
|
17
|
+
xmp = XMP.new('example.jpg')
|
18
|
+
xmp.dc.subject # => ["something interesting"]
|
19
|
+
|
20
|
+
xmp.namespaces.each do |namespace|
|
21
|
+
xmp[namespace].attributes.each do |attribute|
|
22
|
+
puts "#{namespace}.#{attribute}: #{xmp[namespace][attribute].inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
`XMP.new` accepts:
|
28
|
+
* Paths to files (it will choose based on file extension)
|
29
|
+
* File objects (it will choose based on file extension)
|
30
|
+
* Nokogiri documents or XML strings
|
31
|
+
|
32
|
+
Attributes can be accessed in the following ways:
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
# assuming an XMP entry AttributeName within the NamespaceName namespace, these are all equivalent
|
36
|
+
xmp['NamespaceName']['AttributeName']
|
37
|
+
xmp.namespace_name.attribute_name
|
38
|
+
xmp.NamespaceName.AttributeName
|
39
|
+
|
40
|
+
# you can also mix them
|
41
|
+
xmp.namespace_name['AttributeName']
|
42
|
+
|
43
|
+
# or convert the data to an actual hash
|
44
|
+
xmp.to_h # => { 'NamespaceName' => { … }, … }
|
45
|
+
```
|
46
|
+
|
47
|
+
## Installation
|
48
|
+
|
49
|
+
``` shell
|
50
|
+
$ gem install xmp
|
51
|
+
$ gem install exifr # optional, for jpeg/tiff support
|
52
|
+
```
|
53
|
+
|
54
|
+
Or you can add it to your Gemfile:
|
55
|
+
|
56
|
+
``` ruby
|
57
|
+
gem 'xmp', '~> 1.0'
|
58
|
+
gem 'exifr', '~> 1.3'
|
59
|
+
```
|
60
|
+
|
61
|
+
## Requirements
|
62
|
+
* Ruby 2 (supported on >= 2.6, though xmp may work on earlier versions) or Ruby 3
|
63
|
+
* nokogiri (>= 1.10). The xmp gem depends on this gem. It will be installed automatically.
|
64
|
+
* On Ruby 2.6, nokogiri 1.13.10 will be installed; nokogiri >= 1.14 require Ruby 2.7.
|
65
|
+
* On Ruby 2.7, nokogiri 1.15.5 will be installed; nokogiri >= 1.16 require Ruby 3.
|
66
|
+
* See https://nokogiri.org/CHANGELOG.html for nokogiri support for older or newer Ruby versions.
|
67
|
+
* exifr (>= 1.3). This gem is optional. If you need it, add it to your Gemfile.
|
68
|
+
|
69
|
+
## Development
|
70
|
+
|
71
|
+
Fork it at https://github.com/amberbit/xmp
|
72
|
+
|
73
|
+
``` shell
|
74
|
+
$ bundle install # install development dependencies
|
75
|
+
$ rake spec # run specs
|
76
|
+
```
|
77
|
+
|
78
|
+
## License
|
79
|
+
Ruby's license.
|
80
|
+
|
81
|
+
Copyright (c) 2011 Wojciech Piekutowski, AmberBit (<http://amberbit.com>) and contributors.
|
data/Rakefile
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
module XMP::Convenience
|
2
|
+
def include?(key)
|
3
|
+
key_map.include? key
|
4
|
+
end
|
5
|
+
|
6
|
+
def [](key)
|
7
|
+
return unless key = key_map[key]
|
8
|
+
@entries ||= {}
|
9
|
+
@entries[key] ||= get(key)
|
10
|
+
end
|
11
|
+
|
12
|
+
def respond_to_missing?(method_name, include_private = false)
|
13
|
+
include?(method_name) or super
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_h
|
17
|
+
list.map do |key|
|
18
|
+
result = self[key]
|
19
|
+
result = result.to_h if result.is_a? XMP::Convenience
|
20
|
+
[key, result]
|
21
|
+
end.to_h
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def method_missing(method_name, *arguments, &block)
|
27
|
+
return super unless include? method_name
|
28
|
+
raise ArgumentError, "wrong number of arguments (given #{arguments.size}, expected 0)" if arguments.any?
|
29
|
+
self[method_name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def key_map
|
33
|
+
@key_map ||= list.inject({}) do |map, key|
|
34
|
+
underscore_key = key.gsub(/([a-z])([^a-z])|(\d)(\D)|(\D)(\d)/, '\1\3\5_\2\4\6').tr('-', '_').downcase
|
35
|
+
map.merge!(key => key, key.to_sym => key, underscore_key => key, underscore_key.to_sym => key)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/xmp/document.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class XMP::Document
|
2
|
+
include XMP::Convenience
|
3
|
+
|
4
|
+
attr_reader :namespaces
|
5
|
+
attr_reader :xml
|
6
|
+
|
7
|
+
def initialize(doc)
|
8
|
+
@xml = doc.root
|
9
|
+
@namespaces = doc.collect_namespaces.map do |ns, url|
|
10
|
+
@xml.add_namespace_definition ns, url
|
11
|
+
ns[/^(?:xmlns:)?xmlns:(.+)/, 1]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def list
|
18
|
+
namespaces
|
19
|
+
end
|
20
|
+
|
21
|
+
def get(key)
|
22
|
+
XMP::Namespace.new(self, key)
|
23
|
+
end
|
24
|
+
end
|
data/lib/xmp/error.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
begin
|
2
|
+
require 'exifr/jpeg'
|
3
|
+
require 'exifr/tiff'
|
4
|
+
rescue LoadError => exception
|
5
|
+
raise exception unless exception.path == 'exifr/jpeg'
|
6
|
+
end
|
7
|
+
|
8
|
+
module XMP::Handler
|
9
|
+
class Exifr
|
10
|
+
def call(object)
|
11
|
+
return unless defined?(EXIFR::JPEG)
|
12
|
+
case object
|
13
|
+
when EXIFR::JPEG then format, xmp_data = 'jpeg', object.app1s.find { |a| a =~ %r|\Ahttp://ns.adobe.com/xap/1.0/| }&.split("\000")[1]
|
14
|
+
when EXIFR::TIFF then format, xmp_data = 'tiff', object.xmp
|
15
|
+
else return
|
16
|
+
end
|
17
|
+
|
18
|
+
raise XMP::NoXMP, "XMP section missing from #{format}" unless xmp_data
|
19
|
+
xmp_data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module XMP::Handler
|
4
|
+
class File
|
5
|
+
SUPPORTED = [String, Pathname, ::File]
|
6
|
+
attr_reader :extensions, :callback
|
7
|
+
|
8
|
+
def initialize(*extensions, &callback)
|
9
|
+
@extensions = extensions
|
10
|
+
@callback = callback
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(object)
|
14
|
+
return unless SUPPORTED.any? { |c| c === object }
|
15
|
+
return unless path = Pathname(object) and extensions.include? path.extname.downcase
|
16
|
+
return callback.call(object) if object.is_a? IO
|
17
|
+
return path.open(&callback) if path.exist? and path.readable?
|
18
|
+
raise XMP::Error, "cannot read file #{path}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/xmp/handler.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module XMP::Handler
|
2
|
+
attr_accessor :handlers
|
3
|
+
|
4
|
+
def new(object)
|
5
|
+
last_error = nil
|
6
|
+
result = object
|
7
|
+
|
8
|
+
handlers.each do |handler|
|
9
|
+
begin
|
10
|
+
next unless new_result = handler.call(result)
|
11
|
+
return new_result if new_result.is_a? XMP::Document
|
12
|
+
result = new_result
|
13
|
+
rescue XMP::Error => error
|
14
|
+
last_error = error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
raise last_error if last_error
|
19
|
+
raise XMP::Error, "cannot handle #{object.inspect}"
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :parse, :new
|
23
|
+
end
|
data/lib/xmp/namespace.rb
CHANGED
@@ -1,69 +1,52 @@
|
|
1
|
-
class XMP
|
2
|
-
|
3
|
-
|
4
|
-
attr_reader :attributes
|
1
|
+
class XMP::Namespace
|
2
|
+
include XMP::Convenience
|
3
|
+
attr_reader :document, :namespace, :standalone_attributes, :embedded_attributes
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
embedded_attributes =
|
12
|
-
xml.xpath("//rdf:Description").map { |d|
|
13
|
-
d.attributes.values.
|
14
|
-
select { |attr| attr.namespace.prefix.to_s == @namespace }.
|
15
|
-
map(&:name)
|
16
|
-
}.flatten
|
17
|
-
@attributes.concat embedded_attributes
|
18
|
-
standalone_attributes = xml.xpath("//rdf:Description/#{@namespace}:*").
|
19
|
-
map(&:name)
|
20
|
-
@attributes.concat standalone_attributes
|
5
|
+
def initialize(document, namespace)
|
6
|
+
@document, @namespace = document, namespace
|
7
|
+
@standalone_attributes = xml.xpath("//rdf:Description/#{namespace}:*").map(&:name)
|
8
|
+
@embedded_attributes = xml.xpath('//rdf:Description').flat_map do |description|
|
9
|
+
description.attributes.values.select { |attr| attr.namespace.prefix.to_s == namespace }.map(&:name)
|
21
10
|
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def attributes
|
14
|
+
@attributes ||= (standalone_attributes + embedded_attributes).uniq
|
15
|
+
end
|
22
16
|
|
23
|
-
|
24
|
-
"#<XMP::Namespace:#{@namespace}>"
|
25
|
-
end
|
17
|
+
private
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
else
|
31
|
-
super
|
32
|
-
end
|
33
|
-
end
|
19
|
+
def xml
|
20
|
+
document.xml
|
21
|
+
end
|
34
22
|
|
35
|
-
|
36
|
-
|
37
|
-
|
23
|
+
def list
|
24
|
+
attributes
|
25
|
+
end
|
38
26
|
|
39
|
-
|
27
|
+
def get(name)
|
28
|
+
embedded_attributes.include?(name) ? get_embedded(name) : get_standalone(name)
|
29
|
+
end
|
40
30
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
31
|
+
def get_embedded(name)
|
32
|
+
return unless element = xml.at("//rdf:Description[@#{namespace}:#{name}]")
|
33
|
+
element.attribute(name.to_s).text
|
34
|
+
end
|
46
35
|
|
47
|
-
|
48
|
-
|
36
|
+
def get_standalone(name)
|
37
|
+
return unless attribute = xml.xpath("//#{namespace}:#{name}").first
|
38
|
+
if list = attribute.xpath("./rdf:Bag | ./rdf:Seq | ./rdf:Alt").first
|
39
|
+
return list.xpath("./rdf:li").map(&:text)
|
49
40
|
end
|
50
41
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
42
|
+
hash = {}
|
43
|
+
attribute.element_children.each { |c| hash[c.name] = c.text }
|
44
|
+
attribute.attributes.each { |k, v| hash[k] = v.value } if hash.empty?
|
45
|
+
return hash unless hash.empty?
|
55
46
|
|
56
|
-
|
57
|
-
|
58
|
-
items = array_value.xpath("./rdf:li")
|
59
|
-
items.map { |i| i.text }
|
60
|
-
else
|
61
|
-
raise "Don't know how to handle: \n" + attribute.to_s
|
62
|
-
end
|
63
|
-
end
|
47
|
+
text = attribute.text.to_s.strip
|
48
|
+
return text if text.length > 0
|
64
49
|
|
65
|
-
|
66
|
-
@xmp.xml
|
67
|
-
end
|
50
|
+
raise XMP::Error, "Don't know how to handle: \n" + attribute.to_s
|
68
51
|
end
|
69
|
-
end
|
52
|
+
end
|
data/lib/xmp/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION =
|
1
|
+
module XMP
|
2
|
+
VERSION = '1.0.1'
|
3
3
|
end
|
data/lib/xmp.rb
CHANGED
@@ -1,70 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'xmp/
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@xml = doc.root
|
22
|
-
|
23
|
-
available_namespaces = doc.collect_namespaces
|
24
|
-
# let nokogiri know about all namespaces
|
25
|
-
available_namespaces.each do |ns, url|
|
26
|
-
@xml.add_namespace_definition ns, url
|
27
|
-
end
|
28
|
-
|
29
|
-
# collect namespace names
|
30
|
-
@namespaces = available_namespaces.collect do |ns, _|
|
31
|
-
ns =~ /^xmlns:(.+)/
|
32
|
-
$1
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def inspect
|
37
|
-
"#<XMP:@namespaces=#{@namespaces.inspect}>"
|
38
|
-
end
|
39
|
-
|
40
|
-
# returns Namespace object if namespace exists, otherwise tries to call a method
|
41
|
-
def method_missing(namespace, *args)
|
42
|
-
if has_namespace?(namespace)
|
43
|
-
Namespace.new(self, namespace)
|
44
|
-
else
|
45
|
-
super
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def respond_to?(method)
|
50
|
-
has_namespace?(method) or super
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.parse(doc)
|
54
|
-
case doc.class.to_s
|
55
|
-
when 'EXIFR::JPEG'
|
56
|
-
if xmp_chunk = doc.app1s.find { |a| a =~ %r|\Ahttp://ns.adobe.com/xap/1.0/| }
|
57
|
-
xmp_data = xmp_chunk.split("\000")[1]
|
58
|
-
XMP.new(xmp_data)
|
59
|
-
end
|
60
|
-
else
|
61
|
-
raise "Document not supported:\n#{doc.inspect}"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def has_namespace?(namespace)
|
68
|
-
namespaces.include?(namespace.to_s)
|
69
|
-
end
|
70
|
-
end
|
1
|
+
module XMP
|
2
|
+
require 'xmp/convenience'
|
3
|
+
require 'xmp/document'
|
4
|
+
require 'xmp/error'
|
5
|
+
require 'xmp/handler'
|
6
|
+
require 'xmp/handler/exifr'
|
7
|
+
require 'xmp/handler/file'
|
8
|
+
require 'xmp/handler/xml'
|
9
|
+
require 'xmp/namespace'
|
10
|
+
require 'xmp/version'
|
11
|
+
|
12
|
+
extend Handler
|
13
|
+
self.handlers = [
|
14
|
+
Handler::File.new('.jpg', '.jpeg') { |file| EXIFR::JPEG.new(file) },
|
15
|
+
Handler::File.new('.tif', '.tiff') { |file| EXIFR::TIFF.new(file) },
|
16
|
+
Handler::File.new('.xmp', '.xml') { |file| Nokogiri::XML(file) },
|
17
|
+
Handler::Exifr.new,
|
18
|
+
Handler::XML.new
|
19
|
+
]
|
20
|
+
end
|
data/spec/exifr_jpeg_spec.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
require './spec/spec_helper.rb'
|
2
|
+
require 'exifr/jpeg'
|
2
3
|
|
3
4
|
describe "XMP with EXIFR::JPEG" do
|
4
|
-
|
5
|
-
|
5
|
+
it "should parse image given as path" do
|
6
|
+
xmp = XMP.parse('spec/fixtures/multiple-app1.jpg')
|
7
|
+
xmp.should be_instance_of(XMP::Document)
|
8
|
+
xmp.namespaces.should =~ %w{dc iX pdf photoshop rdf tiff x xap xapRights}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should parse image given as path with upper case extension" do
|
12
|
+
xmp = XMP.parse('spec/fixtures/UPPERCASE.JPG')
|
13
|
+
xmp.should be_instance_of(XMP::Document)
|
14
|
+
xmp.namespaces.should =~ %w{dc iX pdf photoshop rdf tiff x xap xapRights}
|
6
15
|
end
|
7
16
|
|
8
|
-
it "should parse image" do
|
9
|
-
|
10
|
-
xmp.
|
17
|
+
it "should parse image given as EXIFR::JPEG" do
|
18
|
+
img = EXIFR::JPEG.new('spec/fixtures/multiple-app1.jpg')
|
19
|
+
xmp = XMP.parse(img)
|
20
|
+
xmp.should be_instance_of(XMP::Document)
|
11
21
|
xmp.namespaces.should =~ %w{dc iX pdf photoshop rdf tiff x xap xapRights}
|
12
22
|
end
|
13
23
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require './spec/spec_helper.rb'
|
2
|
+
require 'exifr/tiff'
|
3
|
+
|
4
|
+
describe "XMP with EXIFR::TIFF" do
|
5
|
+
it "should parse image given as path" do
|
6
|
+
xmp = XMP.parse('spec/fixtures/multiple-app1.tiff')
|
7
|
+
xmp.should be_instance_of(XMP::Document)
|
8
|
+
xmp.namespaces.should =~ %w{dc iX pdf photoshop rdf tiff x xap xapRights}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should parse image given as EXIFR::TIFF" do
|
12
|
+
img = EXIFR::TIFF.new('spec/fixtures/multiple-app1.tiff')
|
13
|
+
xmp = XMP.parse(img)
|
14
|
+
xmp.should be_instance_of(XMP::Document)
|
15
|
+
xmp.namespaces.should =~ %w{dc iX pdf photoshop rdf tiff x xap xapRights}
|
16
|
+
end
|
17
|
+
end
|
Binary file
|
Binary file
|
data/spec/fixtures/xmp.xml
CHANGED
@@ -0,0 +1,62 @@
|
|
1
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.4.0">
|
2
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
3
|
+
<rdf:Description xmlns:aux="http://ns.adobe.com/exif/1.0/aux/" xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/" rdf:about="">
|
4
|
+
<aux:SerialNumber>1981003444</aux:SerialNumber>
|
5
|
+
<aux:FlashCompensation>0/1</aux:FlashCompensation>
|
6
|
+
<aux:ImageNumber>0</aux:ImageNumber>
|
7
|
+
<aux:LensID>237</aux:LensID>
|
8
|
+
<aux:Firmware>2.0.3</aux:Firmware>
|
9
|
+
<aux:LensInfo>24/1 105/1 0/0 0/0</aux:LensInfo>
|
10
|
+
<aux:Lens>EF24-105mm f/4L IS USM</aux:Lens>
|
11
|
+
<Iptc4xmpCore:Location>Phạm Đình Hồ</Iptc4xmpCore:Location>
|
12
|
+
<Iptc4xmpCore:CreatorContactInfo rdf:parseType="Resource">
|
13
|
+
<Iptc4xmpCore:CiAdrCtry>Germany</Iptc4xmpCore:CiAdrCtry>
|
14
|
+
<Iptc4xmpCore:CiAdrCity>Berlin</Iptc4xmpCore:CiAdrCity>
|
15
|
+
</Iptc4xmpCore:CreatorContactInfo>
|
16
|
+
<xmp:ModifyDate>2014-07-06T17:54:07</xmp:ModifyDate>
|
17
|
+
<xmp:CreateDate>2012-12-23T10:38:45</xmp:CreateDate>
|
18
|
+
<xmp:CreatorTool>Adobe Photoshop Lightroom 4.4 (Macintosh)</xmp:CreatorTool>
|
19
|
+
<xmp:Rating>2</xmp:Rating>
|
20
|
+
<dc:subject>
|
21
|
+
<rdf:Bag>
|
22
|
+
<rdf:li>2012</rdf:li>
|
23
|
+
<rdf:li>Asia</rdf:li>
|
24
|
+
<rdf:li>Hanoi</rdf:li>
|
25
|
+
<rdf:li>Vietnam</rdf:li>
|
26
|
+
<rdf:li>food</rdf:li>
|
27
|
+
<rdf:li>frog</rdf:li>
|
28
|
+
<rdf:li>travel</rdf:li>
|
29
|
+
</rdf:Bag>
|
30
|
+
</dc:subject>
|
31
|
+
<dc:description>
|
32
|
+
<rdf:Alt>
|
33
|
+
<rdf:li xml:lang="x-default">This is the Caption</rdf:li>
|
34
|
+
</rdf:Alt>
|
35
|
+
</dc:description>
|
36
|
+
<dc:rights>
|
37
|
+
<rdf:Alt>
|
38
|
+
<rdf:li xml:lang="x-default">© Jens Krämer</rdf:li>
|
39
|
+
</rdf:Alt>
|
40
|
+
</dc:rights>
|
41
|
+
<dc:title>
|
42
|
+
<rdf:Alt>
|
43
|
+
<rdf:li xml:lang="x-default">The title</rdf:li>
|
44
|
+
</rdf:Alt>
|
45
|
+
</dc:title>
|
46
|
+
<dc:creator>
|
47
|
+
<rdf:Seq>
|
48
|
+
<rdf:li>Jens Krämer</rdf:li>
|
49
|
+
</rdf:Seq>
|
50
|
+
</dc:creator>
|
51
|
+
<photoshop:City>Hanoi</photoshop:City>
|
52
|
+
<photoshop:State>Hanoi</photoshop:State>
|
53
|
+
<photoshop:Country>Vietnam</photoshop:Country>
|
54
|
+
<photoshop:DateCreated>2012-12-23T10:38:45</photoshop:DateCreated>
|
55
|
+
<xmpRights:UsageTerms>
|
56
|
+
<rdf:Alt>
|
57
|
+
<rdf:li xml:lang="x-default">All rights reserved</rdf:li>
|
58
|
+
</rdf:Alt>
|
59
|
+
</xmpRights:UsageTerms>
|
60
|
+
</rdf:Description>
|
61
|
+
</rdf:RDF>
|
62
|
+
</x:xmpmeta>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.5-c002 1.148022, 2012/07/15-18:06:45 ">
|
2
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
3
|
+
<rdf:Description xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:aux="http://ns.adobe.com/exif/1.0/aux/" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/" xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/" xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/" rdf:about="" xmp:ModifyDate="2014-06-22T17:42:46+02:00" xmp:CreateDate="2012-12-23T23:39:14" xmp:MetadataDate="2014-06-22T17:42:46+02:00" xmp:Rating="2" xmp:CreatorTool="Adobe Photoshop Lightroom 4.4 (Macintosh)" aux:LensInfo="5200/1000 26000/1000 0/0 0/0" aux:Lens="5.2-26.0 mm" aux:ApproximateFocusDistance="298/100" aux:FlashCompensation="0/1" aux:Firmware="1.01" photoshop:DateCreated="2012-12-23T23:39:14" photoshop:City="Hanoi" photoshop:State="Hanoi" photoshop:Country="Vietnam" xmpMM:DocumentID="xmp.did:28b12b53-d653-4f0a-80ba-67c9f60d68bb" xmpMM:OriginalDocumentID="01AD727BA286F4EF2A360236E69DDE89" xmpMM:InstanceID="xmp.iid:28b12b53-d653-4f0a-80ba-67c9f60d68bb" dc:format="image/jpeg" xmpRights:Marked="True" Iptc4xmpCore:Location="Phạm Đình Hồ" crs:Version="7.4" crs:ProcessVersion="6.7" crs:WhiteBalance="As Shot" crs:Temperature="3100" crs:Tint="+18" crs:Saturation="0" crs:Sharpness="30" crs:LuminanceSmoothing="50" crs:ColorNoiseReduction="25" crs:VignetteAmount="0" crs:ShadowTint="0" crs:RedHue="0" crs:RedSaturation="0" crs:GreenHue="0" crs:GreenSaturation="0" crs:BlueHue="0" crs:BlueSaturation="0" crs:Vibrance="+10" crs:HueAdjustmentRed="0" crs:HueAdjustmentOrange="0" crs:HueAdjustmentYellow="0" crs:HueAdjustmentGreen="0" crs:HueAdjustmentAqua="0" crs:HueAdjustmentBlue="0" crs:HueAdjustmentPurple="0" crs:HueAdjustmentMagenta="0" crs:SaturationAdjustmentRed="0" crs:SaturationAdjustmentOrange="0" crs:SaturationAdjustmentYellow="0" crs:SaturationAdjustmentGreen="0" crs:SaturationAdjustmentAqua="0" crs:SaturationAdjustmentBlue="0" crs:SaturationAdjustmentPurple="0" crs:SaturationAdjustmentMagenta="0" crs:LuminanceAdjustmentRed="0" crs:LuminanceAdjustmentOrange="0" crs:LuminanceAdjustmentYellow="0" crs:LuminanceAdjustmentGreen="0" crs:LuminanceAdjustmentAqua="0" crs:LuminanceAdjustmentBlue="0" crs:LuminanceAdjustmentPurple="0" crs:LuminanceAdjustmentMagenta="0" crs:SplitToningShadowHue="0" crs:SplitToningShadowSaturation="0" crs:SplitToningHighlightHue="0" crs:SplitToningHighlightSaturation="0" crs:SplitToningBalance="0" crs:ParametricShadows="0" crs:ParametricDarks="0" crs:ParametricLights="0" crs:ParametricHighlights="0" crs:ParametricShadowSplit="25" crs:ParametricMidtoneSplit="50" crs:ParametricHighlightSplit="75" crs:SharpenRadius="+1.0" crs:SharpenDetail="25" crs:SharpenEdgeMasking="0" crs:PostCropVignetteAmount="0" crs:GrainAmount="0" crs:LuminanceNoiseReductionDetail="50" crs:ColorNoiseReductionDetail="50" crs:LuminanceNoiseReductionContrast="0" crs:LensProfileEnable="1" crs:LensManualDistortionAmount="0" crs:PerspectiveVertical="0" crs:PerspectiveHorizontal="0" crs:PerspectiveRotate="0.0" crs:PerspectiveScale="100" crs:AutoLateralCA="1" crs:Exposure2012="0.00" crs:Contrast2012="0" crs:Highlights2012="-28" crs:Shadows2012="+28" crs:Whites2012="+4" crs:Blacks2012="+26" crs:Clarity2012="+15" crs:DefringePurpleAmount="0" crs:DefringePurpleHueLo="30" crs:DefringePurpleHueHi="70" crs:DefringeGreenAmount="0" crs:DefringeGreenHueLo="40" crs:DefringeGreenHueHi="60" crs:ConvertToGrayscale="False" crs:ToneCurveName2012="Medium Contrast" crs:CameraProfile="Adobe Standard" crs:LensProfileSetup="LensDefaults" crs:LensProfileName="Adobe (Canon PowerShot S100)" crs:LensProfileFilename="Canon PowerShot S100 - RAW.lcp" crs:LensProfileDigest="D95499C6F0BF984F0C805DC729DE5F48" crs:LensProfileDistortionScale="100" crs:LensProfileChromaticAberrationScale="100" crs:LensProfileVignettingScale="100" crs:HasSettings="True" crs:HasCrop="False" crs:AlreadyApplied="True">
|
4
|
+
<xmpMM:History>
|
5
|
+
<rdf:Seq>
|
6
|
+
<rdf:li stEvt:action="derived" stEvt:parameters="converted from image/x-canon-cr2 to image/jpeg, saved to new location"/>
|
7
|
+
<rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:28b12b53-d653-4f0a-80ba-67c9f60d68bb" stEvt:when="2014-06-22T17:42:46+02:00" stEvt:softwareAgent="Adobe Photoshop Lightroom 4.4 (Macintosh)" stEvt:changed="/"/>
|
8
|
+
</rdf:Seq>
|
9
|
+
</xmpMM:History>
|
10
|
+
<xmpMM:DerivedFrom stRef:documentID="01AD727BA286F4EF2A360236E69DDE89" stRef:originalDocumentID="01AD727BA286F4EF2A360236E69DDE89"/>
|
11
|
+
<dc:creator>
|
12
|
+
<rdf:Seq>
|
13
|
+
<rdf:li>Jens Krämer</rdf:li>
|
14
|
+
</rdf:Seq>
|
15
|
+
</dc:creator>
|
16
|
+
<dc:rights>
|
17
|
+
<rdf:Alt>
|
18
|
+
<rdf:li xml:lang="x-default">© Jens Krämer</rdf:li>
|
19
|
+
</rdf:Alt>
|
20
|
+
</dc:rights>
|
21
|
+
<dc:subject>
|
22
|
+
<rdf:Bag>
|
23
|
+
<rdf:li>2012</rdf:li>
|
24
|
+
<rdf:li>Asia</rdf:li>
|
25
|
+
<rdf:li>Hanoi</rdf:li>
|
26
|
+
<rdf:li>Vietnam</rdf:li>
|
27
|
+
<rdf:li>travel</rdf:li>
|
28
|
+
</rdf:Bag>
|
29
|
+
</dc:subject>
|
30
|
+
<xmpRights:UsageTerms>
|
31
|
+
<rdf:Alt>
|
32
|
+
<rdf:li xml:lang="x-default">All rights reserved</rdf:li>
|
33
|
+
</rdf:Alt>
|
34
|
+
</xmpRights:UsageTerms>
|
35
|
+
<Iptc4xmpCore:CreatorContactInfo Iptc4xmpCore:CiAdrCtry="Germany" Iptc4xmpCore:CiAdrCity="Berlin"/>
|
36
|
+
<crs:ToneCurvePV2012>
|
37
|
+
<rdf:Seq>
|
38
|
+
<rdf:li>0, 0</rdf:li>
|
39
|
+
<rdf:li>32, 22</rdf:li>
|
40
|
+
<rdf:li>64, 56</rdf:li>
|
41
|
+
<rdf:li>128, 128</rdf:li>
|
42
|
+
<rdf:li>192, 196</rdf:li>
|
43
|
+
<rdf:li>255, 255</rdf:li>
|
44
|
+
</rdf:Seq>
|
45
|
+
</crs:ToneCurvePV2012>
|
46
|
+
<crs:ToneCurvePV2012Red>
|
47
|
+
<rdf:Seq>
|
48
|
+
<rdf:li>0, 0</rdf:li>
|
49
|
+
<rdf:li>255, 255</rdf:li>
|
50
|
+
</rdf:Seq>
|
51
|
+
</crs:ToneCurvePV2012Red>
|
52
|
+
<crs:ToneCurvePV2012Green>
|
53
|
+
<rdf:Seq>
|
54
|
+
<rdf:li>0, 0</rdf:li>
|
55
|
+
<rdf:li>255, 255</rdf:li>
|
56
|
+
</rdf:Seq>
|
57
|
+
</crs:ToneCurvePV2012Green>
|
58
|
+
<crs:ToneCurvePV2012Blue>
|
59
|
+
<rdf:Seq>
|
60
|
+
<rdf:li>0, 0</rdf:li>
|
61
|
+
<rdf:li>255, 255</rdf:li>
|
62
|
+
</rdf:Seq>
|
63
|
+
</crs:ToneCurvePV2012Blue>
|
64
|
+
</rdf:Description>
|
65
|
+
</rdf:RDF>
|
66
|
+
</x:xmpmeta>
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/" xmlns:xmlns:x="adobe:ns:meta/" xmlns:xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/" xmlns:xmlns:stArea="http://ns.adobe.com/xmp/sType/Area#" xmlns:xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#" xmlns:xmlns:mwg-rs="http://www.metadataworkinggroup.com/schemas/regions/" xmlns:xmlns:Iptc4xmpExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/" xmlns:xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmlns:exifEX="http://cipa.jp/exif/1.0/" xmlns:xmlns:aux="http://ns.adobe.com/exif/1.0/aux/" xmlns:xmlns:xmp="http://ns.adobe.com/xap/1.0/" x:xmptk="Adobe XMP Core 5.6-c140 79.160451, 2017/05/06-01:08:21 ">
|
2
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
3
|
+
<rdf:Description xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:aux="http://ns.adobe.com/exif/1.0/aux/" xmlns:exifEX="http://cipa.jp/exif/1.0/" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:Iptc4xmpExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/" xmlns:mwg-rs="http://www.metadataworkinggroup.com/schemas/regions/" xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#" xmlns:stArea="http://ns.adobe.com/xmp/sType/Area#" xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/" rdf:about="" xmp:ModifyDate="2020-11-04T18:52:39+01:00" xmp:CreateDate="2019-05-24T15:45:35.65+01:00" xmp:MetadataDate="2020-11-04T18:52:39+01:00" xmp:Label="2019 - 006 - Wedding Sabine & Nils" xmp:CreatorTool="Adobe Photoshop Lightroom Classic 10.0 (Windows)" aux:SerialNumber="053021002918" aux:LensInfo="50/1 50/1 0/0 0/0" aux:Lens="RF50mm F1.2 L USM" aux:LensID="61182" aux:LensSerialNumber="0000000000" aux:ImageNumber="0" aux:ApproximateFocusDistance="249/100" aux:FlashCompensation="0/1" aux:Firmware="1.0.0" exifEX:LensModel="RF50mm F1.2 L USM" photoshop:DateCreated="2019-05-24T15:45:35.65+01:00" xmpMM:DocumentID="xmp.did:f20f4ff3-ea80-f04e-8064-c9ccb27a1133" xmpMM:PreservedFileName="IMG_0259.CR3" xmpMM:OriginalDocumentID="DDD8F3AA8B7D1C0F1BD0D46063A8AA0D" xmpMM:InstanceID="xmp.iid:f20f4ff3-ea80-f04e-8064-c9ccb27a1133" dc:format="image/jpeg" crs:RawFileName="IMG_0259.CR3" crs:Version="13.0" crs:ProcessVersion="11.0" crs:WhiteBalance="As Shot" crs:Temperature="6250" crs:Tint="+9" crs:Exposure2012="0.00" crs:Contrast2012="-43" crs:Highlights2012="0" crs:Shadows2012="+26" crs:Whites2012="+13" crs:Blacks2012="0" crs:Texture="0" crs:Clarity2012="0" crs:Dehaze="-3" crs:Vibrance="+38" crs:Saturation="-20" crs:ParametricShadows="0" crs:ParametricDarks="0" crs:ParametricLights="0" crs:ParametricHighlights="0" crs:ParametricShadowSplit="25" crs:ParametricMidtoneSplit="50" crs:ParametricHighlightSplit="75" crs:Sharpness="25" crs:SharpenRadius="+1.0" crs:SharpenDetail="25" crs:SharpenEdgeMasking="0" crs:LuminanceSmoothing="0" crs:ColorNoiseReduction="25" crs:ColorNoiseReductionDetail="50" crs:ColorNoiseReductionSmoothness="50" crs:HueAdjustmentRed="+5" crs:HueAdjustmentOrange="+3" crs:HueAdjustmentYellow="+31" crs:HueAdjustmentGreen="+15" crs:HueAdjustmentAqua="-40" crs:HueAdjustmentBlue="+15" crs:HueAdjustmentPurple="+2" crs:HueAdjustmentMagenta="-10" crs:SaturationAdjustmentRed="-4" crs:SaturationAdjustmentOrange="+7" crs:SaturationAdjustmentYellow="-54" crs:SaturationAdjustmentGreen="-72" crs:SaturationAdjustmentAqua="-24" crs:SaturationAdjustmentBlue="-30" crs:SaturationAdjustmentPurple="-23" crs:SaturationAdjustmentMagenta="+1" crs:LuminanceAdjustmentRed="+16" crs:LuminanceAdjustmentOrange="+22" crs:LuminanceAdjustmentYellow="+27" crs:LuminanceAdjustmentGreen="+47" crs:LuminanceAdjustmentAqua="+15" crs:LuminanceAdjustmentBlue="-10" crs:LuminanceAdjustmentPurple="+2" crs:LuminanceAdjustmentMagenta="+31" crs:SplitToningShadowHue="31" crs:SplitToningShadowSaturation="4" crs:SplitToningHighlightHue="138" crs:SplitToningHighlightSaturation="3" crs:SplitToningBalance="-62" crs:ColorGradeMidtoneHue="0" crs:ColorGradeMidtoneSat="0" crs:ColorGradeShadowLum="0" crs:ColorGradeMidtoneLum="0" crs:ColorGradeHighlightLum="0" crs:ColorGradeBlending="100" crs:ColorGradeGlobalHue="0" crs:ColorGradeGlobalSat="0" crs:ColorGradeGlobalLum="0" crs:AutoLateralCA="0" crs:LensProfileEnable="0" crs:LensManualDistortionAmount="0" crs:VignetteAmount="0" crs:DefringePurpleAmount="0" crs:DefringePurpleHueLo="30" crs:DefringePurpleHueHi="70" crs:DefringeGreenAmount="0" crs:DefringeGreenHueLo="40" crs:DefringeGreenHueHi="60" crs:PerspectiveUpright="0" crs:PerspectiveVertical="0" crs:PerspectiveHorizontal="0" crs:PerspectiveRotate="0.0" crs:PerspectiveAspect="0" crs:PerspectiveScale="100" crs:PerspectiveX="0.00" crs:PerspectiveY="0.00" crs:GrainAmount="0" crs:PostCropVignetteAmount="0" crs:ShadowTint="0" crs:RedHue="0" crs:RedSaturation="0" crs:GreenHue="0" crs:GreenSaturation="0" crs:BlueHue="0" crs:BlueSaturation="0" crs:ConvertToGrayscale="False" crs:OverrideLookVignette="False" crs:ToneCurveName2012="Custom" crs:CameraProfile="Adobe Standard" crs:CameraProfileDigest="38E531B7F49849F74EF6FA15106BD31D" crs:HasSettings="True" crs:CropTop="0" crs:CropLeft="0" crs:CropBottom="1" crs:CropRight="1" crs:CropAngle="0" crs:CropConstrainToWarp="0" crs:HasCrop="False" crs:AlreadyApplied="True">
|
4
|
+
<xmpMM:History>
|
5
|
+
<rdf:Seq>
|
6
|
+
<rdf:li stEvt:action="derived" stEvt:parameters="converted from image/x-canon-cr3 to image/jpeg, saved to new location"/>
|
7
|
+
<rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:f20f4ff3-ea80-f04e-8064-c9ccb27a1133" stEvt:when="2020-11-04T18:52:39+01:00" stEvt:softwareAgent="Adobe Photoshop Lightroom Classic 10.0 (Windows)" stEvt:changed="/"/>
|
8
|
+
</rdf:Seq>
|
9
|
+
</xmpMM:History>
|
10
|
+
<xmpMM:DerivedFrom stRef:documentID="DDD8F3AA8B7D1C0F1BD0D46063A8AA0D" stRef:originalDocumentID="DDD8F3AA8B7D1C0F1BD0D46063A8AA0D"/>
|
11
|
+
<dc:subject>
|
12
|
+
<rdf:Bag>
|
13
|
+
<rdf:li>A Person</rdf:li>
|
14
|
+
</rdf:Bag>
|
15
|
+
</dc:subject>
|
16
|
+
<Iptc4xmpExt:PersonInImage>
|
17
|
+
<rdf:Bag>
|
18
|
+
<rdf:li>A Person</rdf:li>
|
19
|
+
</rdf:Bag>
|
20
|
+
</Iptc4xmpExt:PersonInImage>
|
21
|
+
<mwg-rs:Regions rdf:parseType="Resource">
|
22
|
+
<mwg-rs:AppliedToDimensions stDim:w="4500" stDim:h="3000" stDim:unit="pixel"/>
|
23
|
+
<mwg-rs:RegionList>
|
24
|
+
<rdf:Bag>
|
25
|
+
<rdf:li>
|
26
|
+
<rdf:Description mwg-rs:Rotation="0.00000" mwg-rs:Name="A Person" mwg-rs:Type="Face">
|
27
|
+
<mwg-rs:Area stArea:h="0.12757" stArea:w="0.08496" stArea:x="0.49268" stArea:y="0.42009"/>
|
28
|
+
</rdf:Description>
|
29
|
+
</rdf:li>
|
30
|
+
</rdf:Bag>
|
31
|
+
</mwg-rs:RegionList>
|
32
|
+
</mwg-rs:Regions>
|
33
|
+
<crs:ToneCurvePV2012>
|
34
|
+
<rdf:Seq>
|
35
|
+
<rdf:li>0, 22</rdf:li>
|
36
|
+
<rdf:li>48, 32</rdf:li>
|
37
|
+
<rdf:li>78, 56</rdf:li>
|
38
|
+
<rdf:li>103, 100</rdf:li>
|
39
|
+
<rdf:li>151, 166</rdf:li>
|
40
|
+
<rdf:li>255, 219</rdf:li>
|
41
|
+
</rdf:Seq>
|
42
|
+
</crs:ToneCurvePV2012>
|
43
|
+
<crs:ToneCurvePV2012Red>
|
44
|
+
<rdf:Seq>
|
45
|
+
<rdf:li>0, 0</rdf:li>
|
46
|
+
<rdf:li>255, 255</rdf:li>
|
47
|
+
</rdf:Seq>
|
48
|
+
</crs:ToneCurvePV2012Red>
|
49
|
+
<crs:ToneCurvePV2012Green>
|
50
|
+
<rdf:Seq>
|
51
|
+
<rdf:li>0, 0</rdf:li>
|
52
|
+
<rdf:li>255, 255</rdf:li>
|
53
|
+
</rdf:Seq>
|
54
|
+
</crs:ToneCurvePV2012Green>
|
55
|
+
<crs:ToneCurvePV2012Blue>
|
56
|
+
<rdf:Seq>
|
57
|
+
<rdf:li>0, 0</rdf:li>
|
58
|
+
<rdf:li>255, 255</rdf:li>
|
59
|
+
</rdf:Seq>
|
60
|
+
</crs:ToneCurvePV2012Blue>
|
61
|
+
</rdf:Description>
|
62
|
+
</rdf:RDF>
|
63
|
+
</x:xmpmeta>
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
|
-
|
2
|
-
require
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.require(:development)
|
3
3
|
|
4
|
-
|
5
|
-
require 'bundler/setup'
|
6
|
-
Bundler.require(:development)
|
7
|
-
}
|
4
|
+
RSpec.configure { |c| c.expect_with(:rspec) { |c| c.syntax = :should } }
|
8
5
|
|
9
6
|
# load whole montgomery after bundler loads required gems
|
10
7
|
require 'xmp'
|
11
|
-
|
12
8
|
require 'pp'
|
data/spec/xmp_spec.rb
CHANGED
@@ -3,16 +3,39 @@ require './spec/spec_helper.rb'
|
|
3
3
|
|
4
4
|
describe XMP do
|
5
5
|
describe "with xmp.xml" do
|
6
|
-
before { @xmp = XMP.new(
|
6
|
+
before { @xmp = XMP.new('spec/fixtures/xmp.xml') }
|
7
7
|
|
8
8
|
it "should return all namespace names" do
|
9
9
|
@xmp.namespaces.should =~ %w{rdf x tiff exif xap aux Iptc4xmpCore photoshop crs dc}
|
10
10
|
end
|
11
11
|
|
12
|
+
it "should support converting to hash via to_h" do
|
13
|
+
hash = @xmp.to_h
|
14
|
+
hash.should be_a(Hash)
|
15
|
+
hash['dc'].should be_a(Hash)
|
16
|
+
hash.keys.should =~ %w{rdf x tiff exif xap aux Iptc4xmpCore photoshop crs dc}
|
17
|
+
hash['dc'].keys.should =~ %w{creator title rights subject description}
|
18
|
+
hash['dc']['title'].should eq(['Tytuł zdjęcia'])
|
19
|
+
end
|
20
|
+
|
12
21
|
it "should return standalone attribute" do
|
13
22
|
@xmp.dc.title.should eq(['Tytuł zdjęcia'])
|
14
23
|
@xmp.dc.subject.should eq(['Słowa kluczowe i numery startowe.'])
|
15
24
|
@xmp.photoshop.SupplementalCategories.should eq(['Nazwa imprezy'])
|
25
|
+
@xmp.photoshop.supplemental_categories.should eq(['Nazwa imprezy'])
|
26
|
+
@xmp['photoshop']['SupplementalCategories'].should eq(['Nazwa imprezy'])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should respond to standalone attributes" do
|
30
|
+
@xmp.should respond_to(:dc)
|
31
|
+
@xmp.dc.should respond_to(:title)
|
32
|
+
@xmp.should respond_to(:photoshop)
|
33
|
+
@xmp.photoshop.should respond_to(:SupplementalCategories)
|
34
|
+
@xmp.photoshop.should respond_to(:supplemental_categories)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return standalone attribute hash" do
|
38
|
+
@xmp.Iptc4xmpCore.CreatorContactInfo.should eq({'CiAdrCtry' => 'Germany', 'CiAdrCity' => 'Berlin'})
|
16
39
|
end
|
17
40
|
|
18
41
|
it "should return embedded attribute" do
|
@@ -22,6 +45,7 @@ describe XMP do
|
|
22
45
|
|
23
46
|
it "should raise NoMethodError on unknown attribute" do
|
24
47
|
lambda { @xmp.photoshop.UnknownAttribute }.should raise_error(NoMethodError)
|
48
|
+
@xmp.photoshop['UnknownAttribute'].should eq(nil)
|
25
49
|
end
|
26
50
|
|
27
51
|
describe "namespace 'tiff'" do
|
@@ -58,4 +82,47 @@ describe XMP do
|
|
58
82
|
@xmp.photoshop.Credit.should eq('Remco')
|
59
83
|
end
|
60
84
|
end
|
85
|
+
|
86
|
+
# metadata after lightroom -> preview (resize)
|
87
|
+
# this one has only standalone attributes
|
88
|
+
describe "with xmp3.xml" do
|
89
|
+
before { @xmp = XMP.new(File.read('spec/fixtures/xmp3.xml')) }
|
90
|
+
|
91
|
+
it "should return attributes" do
|
92
|
+
@xmp.Iptc4xmpCore.Location.should eq('Phạm Đình Hồ')
|
93
|
+
@xmp.photoshop.City.should eq('Hanoi')
|
94
|
+
@xmp.aux.Lens.should eq('EF24-105mm f/4L IS USM')
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return standalone attribute hash" do
|
98
|
+
@xmp.Iptc4xmpCore.CreatorContactInfo.should eq({'CiAdrCtry' => 'Germany', 'CiAdrCity' => 'Berlin'})
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# metadata after lightroom
|
104
|
+
describe "with xmp4.xml" do
|
105
|
+
before { @xmp = XMP.new(File.read('spec/fixtures/xmp4.xml')) }
|
106
|
+
|
107
|
+
it "should return dc:format" do
|
108
|
+
@xmp.dc.format.should eq('image/jpeg')
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return standalone attribute hash" do
|
112
|
+
@xmp.Iptc4xmpCore.CreatorContactInfo.should eq({'CiAdrCtry' => 'Germany', 'CiAdrCity' => 'Berlin'})
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# metadata after lightroom 10 with face recognition
|
117
|
+
describe "with xmp5.xml" do
|
118
|
+
before { @xmp = XMP.new(File.read('spec/fixtures/xmp5.xml')) }
|
119
|
+
|
120
|
+
it "should return dc:format" do
|
121
|
+
@xmp.dc.format.should eq('image/jpeg')
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should be able to read all attribute" do
|
125
|
+
@xmp.to_h.keys.should =~ %w{Iptc4xmpExt aux crs dc exifEX mwg-rs photoshop rdf stArea stDim stEvt stRef x xmp xmpMM}
|
126
|
+
end
|
127
|
+
end
|
61
128
|
end
|
data/xmp.gemspec
CHANGED
@@ -9,20 +9,23 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Wojciech Piekutowski"]
|
10
10
|
s.email = ["wojciech.piekutowski@amberbit.com"]
|
11
11
|
s.homepage = "https://github.com/amberbit/xmp"
|
12
|
-
s.summary = %q{Extensible Metadata Platform (XMP) parser}
|
13
|
-
s.description = %q{Extensible Metadata Platform (XMP) parser}
|
14
|
-
|
15
|
-
s.rubyforge_project = "xmp"
|
12
|
+
s.summary = %q{Extensible Metadata Platform (XMP) parser for JPEG, TIFF and raw XML files}
|
13
|
+
s.description = %q{Extensible Metadata Platform (XMP) parser extracts metadata from JPED and TIFF image files. It also supports parsing raw XML files containing XMP.}
|
14
|
+
s.licenses = ["MIT"]
|
16
15
|
|
17
16
|
s.files = `git ls-files`.split("\n")
|
18
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
19
|
s.require_paths = ["lib"]
|
21
20
|
|
22
|
-
s.extra_rdoc_files = %w(README.
|
21
|
+
s.extra_rdoc_files = %w(README.md)
|
22
|
+
|
23
|
+
s.required_ruby_version = '>= 2.6.0'
|
23
24
|
|
24
|
-
s.add_dependency 'nokogiri', '~>1.
|
25
|
+
s.add_dependency 'nokogiri', '~> 1.0'
|
25
26
|
|
26
|
-
s.add_development_dependency 'exifr', '>=1.0.4'
|
27
|
-
s.add_development_dependency 'rspec', '~>
|
27
|
+
s.add_development_dependency 'exifr', '>= 1.0.4', '~> 1.0'
|
28
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
29
|
+
s.add_development_dependency 'logger', '~> 1.0'
|
30
|
+
s.add_development_dependency 'rake'
|
28
31
|
end
|
metadata
CHANGED
@@ -1,98 +1,163 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Wojciech Piekutowski
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
default_executable:
|
11
|
+
date: 2024-09-14 00:00:00.000000000 Z
|
14
12
|
dependencies:
|
15
13
|
- !ruby/object:Gem::Dependency
|
16
14
|
name: nokogiri
|
17
|
-
requirement:
|
18
|
-
none: false
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
19
16
|
requirements:
|
20
|
-
- - ~>
|
17
|
+
- - "~>"
|
21
18
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
19
|
+
version: '1.0'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
|
-
version_requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
26
27
|
- !ruby/object:Gem::Dependency
|
27
28
|
name: exifr
|
28
|
-
requirement:
|
29
|
-
none: false
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.0.4
|
34
|
+
- - "~>"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '1.0'
|
34
37
|
type: :development
|
35
38
|
prerelease: false
|
36
|
-
version_requirements:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.4
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.0'
|
37
47
|
- !ruby/object:Gem::Dependency
|
38
48
|
name: rspec
|
39
|
-
requirement:
|
40
|
-
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: logger
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '1.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '1.0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rake
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
41
78
|
requirements:
|
42
|
-
- -
|
79
|
+
- - ">="
|
43
80
|
- !ruby/object:Gem::Version
|
44
|
-
version: '
|
81
|
+
version: '0'
|
45
82
|
type: :development
|
46
83
|
prerelease: false
|
47
|
-
version_requirements:
|
48
|
-
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
description: Extensible Metadata Platform (XMP) parser extracts metadata from JPED
|
90
|
+
and TIFF image files. It also supports parsing raw XML files containing XMP.
|
49
91
|
email:
|
50
92
|
- wojciech.piekutowski@amberbit.com
|
51
93
|
executables: []
|
52
94
|
extensions: []
|
53
95
|
extra_rdoc_files:
|
54
|
-
- README.
|
96
|
+
- README.md
|
55
97
|
files:
|
56
|
-
- .gitignore
|
57
|
-
- .rspec
|
58
|
-
- .
|
98
|
+
- ".gitignore"
|
99
|
+
- ".rspec"
|
100
|
+
- ".tool-versions"
|
101
|
+
- ".travis.yml"
|
59
102
|
- Gemfile
|
60
|
-
- README.
|
103
|
+
- README.md
|
61
104
|
- Rakefile
|
62
105
|
- lib/xmp.rb
|
106
|
+
- lib/xmp/convenience.rb
|
107
|
+
- lib/xmp/document.rb
|
108
|
+
- lib/xmp/error.rb
|
109
|
+
- lib/xmp/handler.rb
|
110
|
+
- lib/xmp/handler/exifr.rb
|
111
|
+
- lib/xmp/handler/file.rb
|
112
|
+
- lib/xmp/handler/xml.rb
|
63
113
|
- lib/xmp/namespace.rb
|
64
|
-
- lib/xmp/silencer.rb
|
65
114
|
- lib/xmp/version.rb
|
66
115
|
- spec/exifr_jpeg_spec.rb
|
116
|
+
- spec/exifr_tiff_spec.rb
|
117
|
+
- spec/fixtures/UPPERCASE.JPG
|
67
118
|
- spec/fixtures/multiple-app1.jpg
|
119
|
+
- spec/fixtures/multiple-app1.tiff
|
68
120
|
- spec/fixtures/xmp.xml
|
69
121
|
- spec/fixtures/xmp2.xml
|
122
|
+
- spec/fixtures/xmp3.xml
|
123
|
+
- spec/fixtures/xmp4.xml
|
124
|
+
- spec/fixtures/xmp5.xml
|
70
125
|
- spec/spec_helper.rb
|
71
126
|
- spec/xmp_spec.rb
|
72
127
|
- xmp.gemspec
|
73
|
-
has_rdoc: true
|
74
128
|
homepage: https://github.com/amberbit/xmp
|
75
|
-
licenses:
|
76
|
-
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
77
133
|
rdoc_options: []
|
78
134
|
require_paths:
|
79
135
|
- lib
|
80
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
137
|
requirements:
|
83
|
-
- -
|
138
|
+
- - ">="
|
84
139
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
140
|
+
version: 2.6.0
|
86
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
-
none: false
|
88
142
|
requirements:
|
89
|
-
- -
|
143
|
+
- - ">="
|
90
144
|
- !ruby/object:Gem::Version
|
91
145
|
version: '0'
|
92
146
|
requirements: []
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
147
|
+
rubygems_version: 3.5.16
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: Extensible Metadata Platform (XMP) parser for JPEG, TIFF and raw XML files
|
151
|
+
test_files:
|
152
|
+
- spec/exifr_jpeg_spec.rb
|
153
|
+
- spec/exifr_tiff_spec.rb
|
154
|
+
- spec/fixtures/UPPERCASE.JPG
|
155
|
+
- spec/fixtures/multiple-app1.jpg
|
156
|
+
- spec/fixtures/multiple-app1.tiff
|
157
|
+
- spec/fixtures/xmp.xml
|
158
|
+
- spec/fixtures/xmp2.xml
|
159
|
+
- spec/fixtures/xmp3.xml
|
160
|
+
- spec/fixtures/xmp4.xml
|
161
|
+
- spec/fixtures/xmp5.xml
|
162
|
+
- spec/spec_helper.rb
|
163
|
+
- spec/xmp_spec.rb
|
data/.rvmrc
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# http://rvm.beginrescueend.com/workflow/rvmrc/
|
4
|
-
|
5
|
-
ruby_string="ruby-1.9.2"
|
6
|
-
gemset_name="xmp"
|
7
|
-
|
8
|
-
if rvm list strings | grep -q "${ruby_string}" ; then
|
9
|
-
|
10
|
-
# Load or create the specified environment
|
11
|
-
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
12
|
-
&& -s "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}" ]] ; then
|
13
|
-
\. "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}"
|
14
|
-
else
|
15
|
-
rvm --create "${ruby_string}@${gemset_name}"
|
16
|
-
fi
|
17
|
-
|
18
|
-
# (
|
19
|
-
# Ensure that Bundler is installed, install it if it is not.
|
20
|
-
if ! command -v bundle &> /dev/null; then
|
21
|
-
echo "Installing bundler and creating bundle"
|
22
|
-
gem install bundler
|
23
|
-
bundle
|
24
|
-
fi
|
25
|
-
# )&
|
26
|
-
|
27
|
-
else
|
28
|
-
|
29
|
-
# Notify the user to install the desired interpreter before proceeding.
|
30
|
-
echo "${ruby_string} was not found, please run 'rvm install ${ruby_string}' and then cd back into the project directory."
|
31
|
-
|
32
|
-
fi
|
33
|
-
|
34
|
-
|
data/README.rdoc
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
= xmp - Extensible Metadata Platform (XMP) parser
|
2
|
-
|
3
|
-
XMP provides object oriented interface to XMP data (http://en.wikipedia.org/wiki/Extensible_Metadata_Platform). XMP data can be found in PDF, JPEG, GIF, PNG, and many other formats.
|
4
|
-
|
5
|
-
== Supported formats
|
6
|
-
|
7
|
-
Currently only JPEG is supported through exifr gem.
|
8
|
-
|
9
|
-
== JPEG example
|
10
|
-
|
11
|
-
# gem install xmp exifr
|
12
|
-
require 'xmp'
|
13
|
-
require 'exifr'
|
14
|
-
require 'open-uri'
|
15
|
-
|
16
|
-
img = EXIFR::JPEG.new('spec/fixtures/multiple-app1.jpg')
|
17
|
-
xmp = XMP.parse(img)
|
18
|
-
xmp.dc.subject #=> ["something interesting"]
|
19
|
-
|
20
|
-
# explore XMP data
|
21
|
-
xmp.namespaces.each do |namespace_name|
|
22
|
-
namespace = xmp.send(namespace_name)
|
23
|
-
namespace.attributes.each do |attr|
|
24
|
-
puts "#{namespace_name}.#{attr}: " + namespace.send(attr).inspect
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
== Installation
|
29
|
-
|
30
|
-
gem install xmp
|
31
|
-
# for JPEG support
|
32
|
-
gem install exifr -v ">=1.0.4"
|
33
|
-
|
34
|
-
== Requirements
|
35
|
-
|
36
|
-
* Ruby 1.8.7, 1.9.2
|
37
|
-
* Nokogiri 1.4
|
38
|
-
* EXIFR >= 1.0.4
|
39
|
-
|
40
|
-
== Development
|
41
|
-
|
42
|
-
Fork it at https://github.com/amberbit/xmp
|
43
|
-
|
44
|
-
# install development dependencies
|
45
|
-
bundle install
|
46
|
-
# run specs
|
47
|
-
rake spec
|
48
|
-
|
49
|
-
== License
|
50
|
-
|
51
|
-
Ruby's license.
|
52
|
-
|
53
|
-
Copyright (c) 2011 Wojciech Piekutowski, AmberBit (http://amberbit.com)
|