xmp 0.1.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/README.md +78 -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 +60 -1
- data/xmp.gemspec +11 -8
- metadata +104 -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: 4275b1e67258b6a6b63a3b6c1a61bdaf9b5caf5fa6a6669008ecd6c43d58dd00
|
4
|
+
data.tar.gz: 7bff3b97c76db9f79ed337c84f18177680de92bb48edcd4400f25d8888bf5779
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1056ea809c5e851a3c9b01778a4c6929d73a1f93df0ed592e75d0aca6bb98841156159b744aba7279b6ce4302d6af8d3486ddfae041558f29f4f2b27a3a85f41
|
7
|
+
data.tar.gz: e41d39d8e28bcd2a610257207d24be0c2fd58072e013c9b6c7a1ee4b0fd4fa8a0a29f3ce9bfb0ea4878e97c924716c4c20614545ed2b8f4822e965203c12e1f4
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# xmp - Extensible Metadata Platform (XMP) parser
|
2
|
+
|
3
|
+
MP 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
|
+
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 or Ruby 3
|
63
|
+
* Nokogiri (1.10 or newer, gem dependency - will be installed automatically)
|
64
|
+
* EXIFR (1.3 or newer) - optional
|
65
|
+
|
66
|
+
## Development
|
67
|
+
|
68
|
+
Fork it at https://github.com/amberbit/xmp
|
69
|
+
|
70
|
+
``` shell
|
71
|
+
$ bundle install # install development dependencies
|
72
|
+
$ rake spec # run specs
|
73
|
+
```
|
74
|
+
|
75
|
+
## License
|
76
|
+
Ruby's license.
|
77
|
+
|
78
|
+
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?(key) 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.0'
|
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,31 @@ 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 return standalone attribute hash" do
|
30
|
+
@xmp.Iptc4xmpCore.CreatorContactInfo.should eq({'CiAdrCtry' => 'Germany', 'CiAdrCity' => 'Berlin'})
|
16
31
|
end
|
17
32
|
|
18
33
|
it "should return embedded attribute" do
|
@@ -22,6 +37,7 @@ describe XMP do
|
|
22
37
|
|
23
38
|
it "should raise NoMethodError on unknown attribute" do
|
24
39
|
lambda { @xmp.photoshop.UnknownAttribute }.should raise_error(NoMethodError)
|
40
|
+
@xmp.photoshop['UnknownAttribute'].should eq(nil)
|
25
41
|
end
|
26
42
|
|
27
43
|
describe "namespace 'tiff'" do
|
@@ -58,4 +74,47 @@ describe XMP do
|
|
58
74
|
@xmp.photoshop.Credit.should eq('Remco')
|
59
75
|
end
|
60
76
|
end
|
77
|
+
|
78
|
+
# metadata after lightroom -> preview (resize)
|
79
|
+
# this one has only standalone attributes
|
80
|
+
describe "with xmp3.xml" do
|
81
|
+
before { @xmp = XMP.new(File.read('spec/fixtures/xmp3.xml')) }
|
82
|
+
|
83
|
+
it "should return attributes" do
|
84
|
+
@xmp.Iptc4xmpCore.Location.should eq('Phạm Đình Hồ')
|
85
|
+
@xmp.photoshop.City.should eq('Hanoi')
|
86
|
+
@xmp.aux.Lens.should eq('EF24-105mm f/4L IS USM')
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return standalone attribute hash" do
|
90
|
+
@xmp.Iptc4xmpCore.CreatorContactInfo.should eq({'CiAdrCtry' => 'Germany', 'CiAdrCity' => 'Berlin'})
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
# metadata after lightroom
|
96
|
+
describe "with xmp4.xml" do
|
97
|
+
before { @xmp = XMP.new(File.read('spec/fixtures/xmp4.xml')) }
|
98
|
+
|
99
|
+
it "should return dc:format" do
|
100
|
+
@xmp.dc.format.should eq('image/jpeg')
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should return standalone attribute hash" do
|
104
|
+
@xmp.Iptc4xmpCore.CreatorContactInfo.should eq({'CiAdrCtry' => 'Germany', 'CiAdrCity' => 'Berlin'})
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# metadata after lightroom 10 with face recognition
|
109
|
+
describe "with xmp5.xml" do
|
110
|
+
before { @xmp = XMP.new(File.read('spec/fixtures/xmp5.xml')) }
|
111
|
+
|
112
|
+
it "should return dc:format" do
|
113
|
+
@xmp.dc.format.should eq('image/jpeg')
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should be able to read all attribute" do
|
117
|
+
@xmp.to_h.keys.should =~ %w{Iptc4xmpExt aux crs dc exifEX mwg-rs photoshop rdf stArea stDim stEvt stRef x xmp xmpMM}
|
118
|
+
end
|
119
|
+
end
|
61
120
|
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.7.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,162 @@
|
|
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.0
|
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-09 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
|
+
- ".travis.yml"
|
59
101
|
- Gemfile
|
60
|
-
- README.
|
102
|
+
- README.md
|
61
103
|
- Rakefile
|
62
104
|
- lib/xmp.rb
|
105
|
+
- lib/xmp/convenience.rb
|
106
|
+
- lib/xmp/document.rb
|
107
|
+
- lib/xmp/error.rb
|
108
|
+
- lib/xmp/handler.rb
|
109
|
+
- lib/xmp/handler/exifr.rb
|
110
|
+
- lib/xmp/handler/file.rb
|
111
|
+
- lib/xmp/handler/xml.rb
|
63
112
|
- lib/xmp/namespace.rb
|
64
|
-
- lib/xmp/silencer.rb
|
65
113
|
- lib/xmp/version.rb
|
66
114
|
- spec/exifr_jpeg_spec.rb
|
115
|
+
- spec/exifr_tiff_spec.rb
|
116
|
+
- spec/fixtures/UPPERCASE.JPG
|
67
117
|
- spec/fixtures/multiple-app1.jpg
|
118
|
+
- spec/fixtures/multiple-app1.tiff
|
68
119
|
- spec/fixtures/xmp.xml
|
69
120
|
- spec/fixtures/xmp2.xml
|
121
|
+
- spec/fixtures/xmp3.xml
|
122
|
+
- spec/fixtures/xmp4.xml
|
123
|
+
- spec/fixtures/xmp5.xml
|
70
124
|
- spec/spec_helper.rb
|
71
125
|
- spec/xmp_spec.rb
|
72
126
|
- xmp.gemspec
|
73
|
-
has_rdoc: true
|
74
127
|
homepage: https://github.com/amberbit/xmp
|
75
|
-
licenses:
|
76
|
-
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
77
132
|
rdoc_options: []
|
78
133
|
require_paths:
|
79
134
|
- lib
|
80
135
|
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
136
|
requirements:
|
83
|
-
- -
|
137
|
+
- - ">="
|
84
138
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
139
|
+
version: 2.7.0
|
86
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
-
none: false
|
88
141
|
requirements:
|
89
|
-
- -
|
142
|
+
- - ">="
|
90
143
|
- !ruby/object:Gem::Version
|
91
144
|
version: '0'
|
92
145
|
requirements: []
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
146
|
+
rubygems_version: 3.5.16
|
147
|
+
signing_key:
|
148
|
+
specification_version: 4
|
149
|
+
summary: Extensible Metadata Platform (XMP) parser for JPEG, TIFF and raw XML files
|
150
|
+
test_files:
|
151
|
+
- spec/exifr_jpeg_spec.rb
|
152
|
+
- spec/exifr_tiff_spec.rb
|
153
|
+
- spec/fixtures/UPPERCASE.JPG
|
154
|
+
- spec/fixtures/multiple-app1.jpg
|
155
|
+
- spec/fixtures/multiple-app1.tiff
|
156
|
+
- spec/fixtures/xmp.xml
|
157
|
+
- spec/fixtures/xmp2.xml
|
158
|
+
- spec/fixtures/xmp3.xml
|
159
|
+
- spec/fixtures/xmp4.xml
|
160
|
+
- spec/fixtures/xmp5.xml
|
161
|
+
- spec/spec_helper.rb
|
162
|
+
- 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)
|