exif 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e2d459e26e4c1bc0cc6c02e6c1e87c8a7168796
4
- data.tar.gz: e430895590e8ceaa7595f19c38aa0b062780c527
3
+ metadata.gz: b333d92e91da900e3092613d33281d08b2b83de8
4
+ data.tar.gz: 09eb52bf0bad1c86ff330ebfa8da62543cc76fa3
5
5
  SHA512:
6
- metadata.gz: 5e5b91c5f772dbdc7c8bef203b2101b8f57122c081a30ef841da082de6ba42cd8c942698024678136930ae895a95f59931b28ea4dc7e988d2f4445ae5d38bf48
7
- data.tar.gz: 9dd8285f7a418fed4bf545be7039feb702bd246aa524754090a88196a573adbd491c9a005736c3eaff8458338bdeaabb182d6e02cf83756eed229f2daf1d4395
6
+ metadata.gz: 27d623c15fb6ad2a9ac9e65ff960220bd5afa5ae1899e8eb0a0f5e009b79746a9aced6b1285b2a699507a1e84ad52957950737539a9b787d7c37a581ee30df9e
7
+ data.tar.gz: 1a3d1eaf3eb5f7be85f5badca07a174df54a6df99664a092854c8cbfff22799adab34592729c354261403a518e6221abee7c1b9885bfed15183cd7f2b69dabaa
data/README.md CHANGED
@@ -1,27 +1,61 @@
1
- # Exif
2
-
3
- Ruby wrapper for libexif
1
+ Ruby EXIF reader written in C extension.
4
2
 
5
3
  # Installation
6
4
 
7
5
  $ gem install exif
8
6
 
7
+ Please make sure you have installed `libexif` first.
8
+
9
9
  # Usage
10
10
 
11
11
  ```ruby
12
12
  data = Exif::Data.new('sample.jpg')
13
+ data.model # => "NIKON D600"
13
14
  data.image_width # => 4000
14
- data.gps_latitude # => '24, 10.6817, 0'
15
+ data.gps_longitude # => 121.51246
16
+ data.date_time # => 2013-12-08 21:14:11 0800
15
17
 
16
18
  # get all entries in an IFD
17
19
  data[0] # => {image_width: 4000, image_length: 2670, ...}
18
- data[1] # => {x_resolution: "72"}, y_resolution: "72", ...}
20
+ data[1] # => {x_resolution: "72", y_resolution: "72", ...}
19
21
  data[:exif] # => exposure_time: "1/125 sec.", f_number: "f/8.0"}
20
22
  data[:gps] # => {gps_version_id: "2.2.0.0", gps_latitude_ref: "N", ...}
21
23
  data[:interoperability] # => {...}
22
24
  data.to_h # => {0 => {...}, 1 => {...}, :exif => {...}}
23
25
  ```
24
26
 
27
+ # How fast?
28
+
29
+ There is another excellent work called [exifr](https://github.com/remvee/exifr) made by [@remvee](https://github.com/remvee). That's pure Ruby while this one is C extension. If you program JRuby, you may want to choose exifr, otherwise you can try this gem for speed purpose, it's about 8 times faster. A small benchmark shows below:
30
+
31
+ ```ruby
32
+ require 'benchmark'
33
+ require 'exif'
34
+ require 'exifr'
35
+ N = 500
36
+ FILE_PATH = 'sample.jpg'
37
+ Benchmark.bmbm do |x|
38
+ x.report '[exifr] init' do
39
+ N.times{ EXIFR::JPEG.new(FILE_PATH).width }
40
+ end
41
+ x.report '[exif] init' do
42
+ N.times{ Exif::Data.new(FILE_PATH).image_width }
43
+ end
44
+ end
45
+ ```
46
+
47
+ ```
48
+ $ ruby benchmark/benchmark.rb
49
+ Rehearsal ------------------------------------------------
50
+ [exifr] init 0.810000 0.020000 0.830000 ( 0.840701)
51
+ [exif] init 0.090000 0.010000 0.100000 ( 0.099700)
52
+ --------------------------------------- total: 0.930000sec
53
+
54
+ user system total real
55
+ [exifr] init 0.810000 0.020000 0.830000 ( 0.830644)
56
+ [exif] init 0.090000 0.010000 0.100000 ( 0.095148)
57
+ ```
58
+
25
59
  ## Tag Rreference
26
60
 
27
61
  - aperture_value
@@ -5,8 +5,6 @@ require 'exifr'
5
5
 
6
6
  N = 500
7
7
  FILE_PATH = File.expand_path('../../spec/sample.jpg', __FILE__)
8
- exifr = EXIFR::JPEG.new(FILE_PATH)
9
- exif = Exif::Data.new(FILE_PATH)
10
8
  Benchmark.bmbm do |x|
11
9
  x.report '[exifr] init' do
12
10
  N.times{ EXIFR::JPEG.new(FILE_PATH).width }
@@ -14,10 +12,4 @@ Benchmark.bmbm do |x|
14
12
  x.report '[exif] init' do
15
13
  N.times{ Exif::Data.new(FILE_PATH).image_width }
16
14
  end
17
- x.report '[exifr] get width' do
18
- N.times{ exifr.width }
19
- end
20
- x.report '[exif] get width' do
21
- N.times{ exif.image_width }
22
- end
23
15
  end
data/exif.gemspec CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Jian Weihang"]
10
10
  spec.email = ["tonytonyjan@gmail.com"]
11
11
  spec.extensions = ["ext/exif/extconf.rb"]
12
- spec.summary = %q{Wrapper of libexif}
13
- spec.description = %q{Wrapper of libexif}
12
+ spec.summary = %q{Ruby EXIF reader written in C extension.}
13
+ spec.description = %q{Ruby EXIF reader written in C extension.}
14
14
  spec.homepage = "https://github.com/tonytonyjan/exif"
15
15
  spec.license = "MIT"
16
16
 
data/ext/exif/data.c CHANGED
@@ -1,4 +1,5 @@
1
1
  #include <libexif/exif-data.h>
2
+ #include <time.h>
2
3
  #include "data.h"
3
4
 
4
5
  extern VALUE rb_mExif;
@@ -93,13 +94,59 @@ static void each_entry(ExifEntry *ee, void *self_ptr){
93
94
  value = rb_float_new(atof(buf));
94
95
  break;
95
96
  default:
96
- value = rb_str_new_cstr(buf);
97
+ value = process_value(self, ee->tag, buf);
97
98
  }
98
99
  rb_hash_aset(rb_hash_aref(rb_contents, IFD2SYM[ifd]), tag_name, value);
99
100
  rb_hash_aset(rb_contents, tag_name, value);
100
101
  rb_iv_set(*self, attr_name, value);
101
102
  }
102
103
 
104
+ static VALUE process_value(VALUE *self_ptr, ExifTag tag, char *buf){
105
+ ExifData *ed;
106
+ Data_Get_Struct(*self_ptr, ExifData, ed);
107
+ switch((int)tag){
108
+ case EXIF_TAG_DATE_TIME:
109
+ case EXIF_TAG_DATE_TIME_ORIGINAL:
110
+ case EXIF_TAG_DATE_TIME_DIGITIZED:
111
+ {
112
+ int i;
113
+ struct tm timer;
114
+ // "2013:09:10 16:31:21"
115
+ buf[4] = buf[7] = buf[10] = buf[13] = buf[16] = '\0';
116
+ timer.tm_year = atoi(buf) - 1900;
117
+ timer.tm_mon = atoi(buf + 5) - 1;
118
+ timer.tm_mday = atoi(buf + 8);
119
+ timer.tm_hour = atoi(buf + 11);
120
+ timer.tm_min = atoi(buf + 14);
121
+ timer.tm_sec = atoi(buf + 17);
122
+ return rb_time_new(mktime(&timer), 0);
123
+ break;
124
+ }
125
+ case EXIF_TAG_GPS_LATITUDE:
126
+ case EXIF_TAG_GPS_LONGITUDE:
127
+ {
128
+ char *l = buf, *r = buf + 1;
129
+ double degrees, minutes, seconds;
130
+ // "121, 30.7476, 0"
131
+ while(*r != ',') r++;
132
+ *r = '\0'; r++;
133
+ degrees = atof(l); l = r;
134
+ while(*r != ',') r++;
135
+ *r = '\0';
136
+ minutes = atof(l); l = r + 1;
137
+ seconds = atof(l);
138
+ ExifTag ref_tag = tag == EXIF_TAG_GPS_LATITUDE ? EXIF_TAG_GPS_LATITUDE_REF : EXIF_TAG_GPS_LONGITUDE_REF;
139
+ ExifEntry *entry = exif_content_get_entry(ed->ifd[EXIF_IFD_GPS], ref_tag);
140
+ char ref_value; exif_entry_get_value(entry, &ref_value, 1);
141
+ double degree = (degrees * 3600 + minutes * 60 + seconds) / 3600;
142
+ if(ref_value == 'S' || ref_value == 'W') degree *= -1;
143
+ return rb_float_new(degree);
144
+ }
145
+ default:
146
+ return rb_str_new_cstr(buf);
147
+ }
148
+ }
149
+
103
150
  static char* attr_string(ExifIfd ifd, ExifTag tag){
104
151
  switch((int)tag){
105
152
  case EXIF_TAG_INTEROPERABILITY_INDEX: /* EXIF_TAG_GPS_LATITUDE_REF */
data/ext/exif/data.h CHANGED
@@ -14,6 +14,7 @@ static VALUE rb_value(VALUE self, VALUE key);
14
14
 
15
15
  static void each_content(ExifContent *ec, void *user_data);
16
16
  static void each_entry(ExifEntry *, void *user_data);
17
+ static VALUE process_value(VALUE *self_ptr, ExifTag tag, char *buf);
17
18
  static char* attr_string(ExifIfd ifd, ExifTag tag);
18
19
 
19
20
  #endif /* DATA_H */
data/lib/exif/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Exif
2
- VERSION = "0.10.0"
2
+ VERSION = "0.11.0"
3
3
  end
data/spec/exif_spec.rb CHANGED
@@ -10,15 +10,9 @@ describe Exif do
10
10
  # end
11
11
 
12
12
  it 'works' do
13
- expect(@data.to_h[0][:image_width]).to eq 4000
14
- expect(@data.to_h[:image_width]).to eq 4000
15
- expect(@data[0][:image_width]).to eq 4000
16
- expect(@data[:image_width]).to eq 4000
13
+ expect(@data.model).to eq 'NIKON D600'
17
14
  expect(@data.image_width).to eq 4000
18
- expect(@data.to_h[:gps][:gps_latitude]).to eq '24, 10.6817, 0'
19
- expect(@data.to_h[:gps_latitude]).to eq '24, 10.6817, 0'
20
- expect(@data[:gps][:gps_latitude]).to eq '24, 10.6817, 0'
21
- expect(@data[:gps_latitude]).to eq '24, 10.6817, 0'
22
- expect(@data.gps_latitude).to eq '24, 10.6817, 0'
15
+ expect(@data.gps_latitude).to be_within(0.0001).of(24.178028333333334)
16
+ expect(@data.date_time).to eq Time.new(2013,12,8,21,14,11)
23
17
  end
24
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exif
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jian Weihang
@@ -52,7 +52,7 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description: Wrapper of libexif
55
+ description: Ruby EXIF reader written in C extension.
56
56
  email:
57
57
  - tonytonyjan@gmail.com
58
58
  executables: []
@@ -101,7 +101,7 @@ rubyforge_project:
101
101
  rubygems_version: 2.4.2
102
102
  signing_key:
103
103
  specification_version: 4
104
- summary: Wrapper of libexif
104
+ summary: Ruby EXIF reader written in C extension.
105
105
  test_files:
106
106
  - spec/exif_spec.rb
107
107
  - spec/sample.jpg