exiv2 0.0.1 → 0.0.2

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.
@@ -4,6 +4,8 @@ A simple wrapper around the C++ Exiv2 libary for reading image metadata.
4
4
 
5
5
  See http://www.exiv2.org/
6
6
 
7
+ Requires that the exiv2 C++ library is installed.
8
+
7
9
  == Usage
8
10
 
9
11
  gem install exiv2
@@ -11,8 +13,10 @@ See http://www.exiv2.org/
11
13
  require 'exiv2'
12
14
  image = Exiv2::ImageFactory.open("image.jpg")
13
15
  image.read_metadata
14
- puts image.exif_data.inspect
15
- puts image.iptc_data.inspect
16
+ image.iptc_data.each do |key, value|
17
+ puts "#{key} = #{value}\n"
18
+ end
19
+ image.exif_data.each { ... }
16
20
 
17
21
  == Why?
18
22
 
@@ -11,20 +11,22 @@ static std::string to_std_string(VALUE string) {
11
11
  return std::string(RSTRING(string)->ptr, RSTRING(string)->len);
12
12
  }
13
13
 
14
- // Extract data from an Exiv2::IptcData or an Exiv2::ExifData into a Ruby hash.
14
+ // Shared method for implementing each on IptcData and ExifData.
15
15
  template <class T>
16
- static VALUE data_to_hash(T& data) {
17
- VALUE hash = rb_hash_new();
16
+ static VALUE metadata_each(VALUE self) {
17
+ T* data;
18
+ Data_Get_Struct(self, T, data);
18
19
 
19
- for(typename T::iterator i = data.begin(); i != data.end(); i++) {
20
+ for(typename T::iterator i = data->begin(); i != data->end(); i++) {
20
21
  VALUE key = to_ruby_string(i->key());
21
22
  VALUE value = to_ruby_string(i->value().toString());
22
- rb_hash_aset(hash, key, value);
23
+ rb_yield(rb_ary_new3(2, key, value));
23
24
  }
24
25
 
25
- return hash;
26
+ return Qnil;
26
27
  }
27
28
 
29
+
28
30
  extern "C" {
29
31
  typedef VALUE (*Method)(...);
30
32
 
@@ -41,8 +43,16 @@ extern "C" {
41
43
  static VALUE image_factory_class;
42
44
  static VALUE image_factory_open(VALUE klass, VALUE path);
43
45
 
46
+ static VALUE exif_data_class;
47
+ static VALUE exif_data_each(VALUE self);
48
+
49
+ static VALUE iptc_data_class;
50
+ static VALUE iptc_data_each(VALUE self);
51
+
44
52
 
45
53
  void Init_exiv2() {
54
+ VALUE enumerable_module = rb_const_get(rb_cObject, rb_intern("Enumerable"));
55
+
46
56
  exiv2_module = rb_define_module("Exiv2");
47
57
 
48
58
  basic_error_class = rb_define_class_under(exiv2_module, "BasicError", rb_eRuntimeError);
@@ -54,6 +64,14 @@ extern "C" {
54
64
 
55
65
  image_factory_class = rb_define_class_under(exiv2_module, "ImageFactory", rb_cObject);
56
66
  rb_define_singleton_method(image_factory_class, "open", (Method)image_factory_open, 1);
67
+
68
+ exif_data_class = rb_define_class_under(exiv2_module, "ExifData", rb_cObject);
69
+ rb_include_module(exif_data_class, enumerable_module);
70
+ rb_define_method(exif_data_class, "each", (Method)exif_data_each, 0);
71
+
72
+ iptc_data_class = rb_define_class_under(exiv2_module, "IptcData", rb_cObject);
73
+ rb_include_module(iptc_data_class, enumerable_module);
74
+ rb_define_method(iptc_data_class, "each", (Method)iptc_data_each, 0);
57
75
  }
58
76
 
59
77
 
@@ -81,14 +99,20 @@ extern "C" {
81
99
  Exiv2::Image* image;
82
100
  Data_Get_Struct(self, Exiv2::Image, image);
83
101
 
84
- return data_to_hash<Exiv2::ExifData>(image->exifData());
102
+ VALUE exif_data = Data_Wrap_Struct(exif_data_class, 0, 0, &image->exifData());
103
+ rb_iv_set(exif_data, "@image", self); // Make sure we don't GC the image until there are no references to the EXIF data left.
104
+
105
+ return exif_data;
85
106
  }
86
107
 
87
108
  static VALUE image_iptc_data(VALUE self) {
88
109
  Exiv2::Image* image;
89
110
  Data_Get_Struct(self, Exiv2::Image, image);
90
111
 
91
- return data_to_hash<Exiv2::IptcData>(image->iptcData());
112
+ VALUE iptc_data = Data_Wrap_Struct(iptc_data_class, 0, 0, &image->iptcData());
113
+ rb_iv_set(iptc_data, "@image", self); // Make sure we don't GC the image until there are no references to the IPTC data left.
114
+
115
+ return iptc_data;
92
116
  }
93
117
 
94
118
 
@@ -108,4 +132,18 @@ extern "C" {
108
132
  return Data_Wrap_Struct(image_class, 0, image_free, image);
109
133
  }
110
134
 
135
+
136
+ // Exiv2::ExifData methods
137
+
138
+ static VALUE exif_data_each(VALUE self) {
139
+ return metadata_each<Exiv2::ExifData>(self);
140
+ }
141
+
142
+
143
+ // Exiv2::IptcData methods
144
+
145
+ static VALUE iptc_data_each(VALUE self) {
146
+ return metadata_each<Exiv2::IptcData>(self);
147
+ }
148
+
111
149
  }
@@ -1 +1,2 @@
1
1
  require 'exiv2/exiv2'
2
+ require 'exiv2/iptc_data'
@@ -0,0 +1,22 @@
1
+ class Exiv2::IptcData
2
+ def to_hash
3
+ result = {}
4
+
5
+ self.each do |key, value|
6
+ if result[key]
7
+ if result[key].is_a? Array
8
+ result[key] << value
9
+ else
10
+ result[key] = [result[key], value]
11
+ end
12
+ else
13
+ result[key] = value
14
+ end
15
+ end
16
+ result
17
+ end
18
+
19
+ def inspect
20
+ "#<Exiv2::IptcData: #{self.to_hash.inspect}>"
21
+ end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module Exiv2
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -4,8 +4,24 @@ describe Exiv2 do
4
4
  it "should read IPTC data" do
5
5
  image = Exiv2::ImageFactory.open("spec/files/test.jpg")
6
6
  image.read_metadata
7
- image.iptc_data.should == {
8
- "Iptc.Application2.Caption" => "Rhubarb rhubarb rhubard"
7
+ iptc_data = image.iptc_data
8
+ iptc_data.should be_a(Exiv2::IptcData)
9
+ iptc_data.inspect.should == '#<Exiv2::IptcData: {"Iptc.Application2.Caption"=>"Rhubarb rhubarb rhubard", "Iptc.Application2.Keywords"=>["fish", "custard"]}>'
10
+ iptc_data.to_a.should == [
11
+ ["Iptc.Application2.Caption", "Rhubarb rhubarb rhubard"],
12
+ ["Iptc.Application2.Keywords", "fish"],
13
+ ["Iptc.Application2.Keywords", "custard"]
14
+ ]
15
+ end
16
+
17
+ it "should convert iptc data into a hash" do
18
+ image = Exiv2::ImageFactory.open("spec/files/test.jpg")
19
+ image.read_metadata
20
+ iptc_hash = image.iptc_data.to_hash
21
+ iptc_hash.should be_a(Hash)
22
+ iptc_hash.should == {
23
+ "Iptc.Application2.Caption" => "Rhubarb rhubarb rhubard",
24
+ "Iptc.Application2.Keywords" => ["fish", "custard"]
9
25
  }
10
26
  end
11
27
 
Binary file
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exiv2
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pete Yandell
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-24 00:00:00 +11:00
18
+ date: 2011-01-27 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -66,6 +66,7 @@ files:
66
66
  - ext/exiv2/exiv2.cpp
67
67
  - ext/exiv2/extconf.rb
68
68
  - lib/exiv2.rb
69
+ - lib/exiv2/iptc_data.rb
69
70
  - lib/exiv2/version.rb
70
71
  - spec/exiv2_spec.rb
71
72
  - spec/files/test.jpg