exiv2 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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