ruby-exiv2 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +10 -10
- data/Rakefile +4 -2
- data/ext/exif.cpp +28 -2
- data/ext/exiv2.cpp +9 -0
- data/ext/image.cpp +12 -4
- data/ext/iptc.cpp +7 -1
- data/ext/marshall.cpp +6 -1
- data/lib/exiv2.rb +11 -0
- data/test/image.rb +7 -0
- metadata +2 -2
data/README
CHANGED
@@ -2,15 +2,15 @@ Library for handling exif image tags.
|
|
2
2
|
|
3
3
|
Basic usage:
|
4
4
|
|
5
|
-
> gem install ruby-exiv2
|
6
|
-
> irb -r rubygems
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
> gem install ruby-exiv2
|
6
|
+
> irb -r rubygems
|
7
|
+
|
8
|
+
require 'exiv2'
|
9
|
+
@img = Exiv2::Image.new("a.jpg")
|
10
|
+
puts @img["Exif.Photo.PixelXDimension"]
|
11
|
+
@img["Exif.Photo.PixelXDimension"] = 2048
|
12
|
+
@img.save
|
13
|
+
|
14
|
+
|
15
15
|
|
16
16
|
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'rake/packagetask'
|
|
6
6
|
require 'rake/contrib/rubyforgepublisher'
|
7
7
|
|
8
8
|
PKG_NAME = "ruby-exiv2"
|
9
|
-
PKG_VERSION = "1.
|
9
|
+
PKG_VERSION = "1.2"
|
10
10
|
PKG_AUTHOR = "Max Lapshin"
|
11
11
|
PKG_EMAIL = "max@maxidoors.ru"
|
12
12
|
PKG_HOMEPAGE = "http://maxidoors.ru/"
|
@@ -63,9 +63,10 @@ task :stats do
|
|
63
63
|
).to_s
|
64
64
|
end
|
65
65
|
|
66
|
+
`rm -f ruby-exiv2.cpp`
|
66
67
|
desc "Generate file with C++ with all methods for proper rdoc"
|
67
68
|
file "ruby-exiv2.cpp" do
|
68
|
-
`cat
|
69
|
+
`cat ext/*.cpp > ruby-exiv2.cpp`
|
69
70
|
end
|
70
71
|
|
71
72
|
|
@@ -90,6 +91,7 @@ desc "Remove packaging products (doc and pkg) - they are not source-managed"
|
|
90
91
|
task :clobber do
|
91
92
|
`rm -rf ./doc`
|
92
93
|
`rm -rf ./pkg`
|
94
|
+
`rm -f ruby-exiv2`
|
93
95
|
end
|
94
96
|
|
95
97
|
desc "Publish the new docs"
|
data/ext/exif.cpp
CHANGED
@@ -58,9 +58,15 @@ static bool marshall_value(Exiv2::ExifData &data, const char* key, VALUE value)
|
|
58
58
|
data[key] = Exiv2::DateValue(year, month, day);
|
59
59
|
return true;
|
60
60
|
}
|
61
|
+
case Exiv2::time: {
|
62
|
+
int hour = NUM2INT(rb_funcall(value, rb_intern("hour"), 0));
|
63
|
+
int minute = NUM2INT(rb_funcall(value, rb_intern("min"), 0));
|
64
|
+
int second = NUM2INT(rb_funcall(value, rb_intern("sec"), 0));
|
65
|
+
data[key] = Exiv2::TimeValue(hour, minute, second);
|
66
|
+
return true;
|
67
|
+
}
|
61
68
|
|
62
69
|
case Exiv2::invalid6:
|
63
|
-
case Exiv2::time:
|
64
70
|
case Exiv2::comment:
|
65
71
|
case Exiv2::directory:
|
66
72
|
case Exiv2::lastTypeId:
|
@@ -248,6 +254,9 @@ static int iterate_tag_collection(const Exiv2::TagInfo* collection, bool to_yiel
|
|
248
254
|
return i;
|
249
255
|
}
|
250
256
|
|
257
|
+
/*
|
258
|
+
* Iterates through all available exif tags, that can be set in the image
|
259
|
+
*/
|
251
260
|
static VALUE exiv2_tags_each(VALUE self) {
|
252
261
|
__BEGIN
|
253
262
|
iterate_tag_collection(Exiv2::ExifTags::ifdTagList());
|
@@ -259,7 +268,9 @@ static VALUE exiv2_tags_each(VALUE self) {
|
|
259
268
|
}
|
260
269
|
|
261
270
|
|
262
|
-
|
271
|
+
/*
|
272
|
+
* Count of all available exif tags
|
273
|
+
*/
|
263
274
|
static VALUE exiv2_tags_count(VALUE self) {
|
264
275
|
__BEGIN
|
265
276
|
return INT2NUM(
|
@@ -272,6 +283,9 @@ static VALUE exiv2_tags_count(VALUE self) {
|
|
272
283
|
}
|
273
284
|
#endif /* HAVE_IFDTAGLIST */
|
274
285
|
|
286
|
+
/*
|
287
|
+
* Name of exif tag
|
288
|
+
*/
|
275
289
|
static VALUE exiv2_tag_name(VALUE self) {
|
276
290
|
__BEGIN
|
277
291
|
Exiv2::TagInfo* tag;
|
@@ -281,6 +295,9 @@ static VALUE exiv2_tag_name(VALUE self) {
|
|
281
295
|
__END
|
282
296
|
}
|
283
297
|
|
298
|
+
/*
|
299
|
+
* title of exif tag
|
300
|
+
*/
|
284
301
|
static VALUE exiv2_tag_title(VALUE self) {
|
285
302
|
__BEGIN
|
286
303
|
Exiv2::TagInfo* tag;
|
@@ -290,6 +307,9 @@ static VALUE exiv2_tag_title(VALUE self) {
|
|
290
307
|
__END
|
291
308
|
}
|
292
309
|
|
310
|
+
/*
|
311
|
+
* description of exif tag
|
312
|
+
*/
|
293
313
|
static VALUE exiv2_tag_desc(VALUE self) {
|
294
314
|
__BEGIN
|
295
315
|
Exiv2::TagInfo* tag;
|
@@ -299,6 +319,9 @@ static VALUE exiv2_tag_desc(VALUE self) {
|
|
299
319
|
__END
|
300
320
|
}
|
301
321
|
|
322
|
+
/*
|
323
|
+
* section of exif tag
|
324
|
+
*/
|
302
325
|
static VALUE exiv2_tag_section(VALUE self) {
|
303
326
|
__BEGIN
|
304
327
|
Exiv2::TagInfo* tag;
|
@@ -308,6 +331,9 @@ static VALUE exiv2_tag_section(VALUE self) {
|
|
308
331
|
__END
|
309
332
|
}
|
310
333
|
|
334
|
+
/*
|
335
|
+
* IFD of exif tag
|
336
|
+
*/
|
311
337
|
static VALUE exiv2_tag_ifd(VALUE self) {
|
312
338
|
__BEGIN
|
313
339
|
Exiv2::TagInfo* tag;
|
data/ext/exiv2.cpp
CHANGED
@@ -49,7 +49,16 @@ void rb_exiv2_throw(const char *file, long unsigned int line, const char *fmt, .
|
|
49
49
|
extern "C"
|
50
50
|
#endif
|
51
51
|
|
52
|
+
/*
|
53
|
+
* Document-module: Exiv2
|
54
|
+
*
|
55
|
+
* Namespace for all exiv stuff
|
56
|
+
*/
|
52
57
|
|
58
|
+
/*
|
59
|
+
* Document-class: Exiv2::Error
|
60
|
+
* error, thrown if anything goes wrong inside in exiv2
|
61
|
+
*/
|
53
62
|
|
54
63
|
void Init_exiv2_bin() {
|
55
64
|
mExiv2 = rb_define_module("Exiv2");
|
data/ext/image.cpp
CHANGED
@@ -13,6 +13,14 @@ static void image_leave(rbImage* image) {
|
|
13
13
|
|
14
14
|
}
|
15
15
|
|
16
|
+
/*
|
17
|
+
* Document-class: Exiv2::Image
|
18
|
+
* Image is used to access to all exif data of image
|
19
|
+
*
|
20
|
+
* @image = Exiv2::Image.new("my.jpg")
|
21
|
+
* puts @image["Iptc.Application2.DateCreated"]
|
22
|
+
* puts @image["Exif.Image.Software"]
|
23
|
+
*/
|
16
24
|
static VALUE exiv2_image_s_allocate(VALUE klass) {
|
17
25
|
__BEGIN
|
18
26
|
rbImage* image = new rbImage();
|
@@ -22,8 +30,7 @@ static VALUE exiv2_image_s_allocate(VALUE klass) {
|
|
22
30
|
}
|
23
31
|
|
24
32
|
/*
|
25
|
-
*
|
26
|
-
* => #<Exiv2::Image:0x844bc>
|
33
|
+
* img = Exiv2::Image.new("IMGP3025.jpg")
|
27
34
|
*/
|
28
35
|
static VALUE exiv2_image_initialize(VALUE self, VALUE file) {
|
29
36
|
__BEGIN
|
@@ -51,8 +58,9 @@ static VALUE exiv2_image_initialize(VALUE self, VALUE file) {
|
|
51
58
|
/*
|
52
59
|
*
|
53
60
|
* Load Exiv2::Image from memory string
|
54
|
-
*
|
55
|
-
*
|
61
|
+
*
|
62
|
+
* content = File.open("a.jpg").read
|
63
|
+
* img = Exiv2::Image.load_string(content)
|
56
64
|
*/
|
57
65
|
static VALUE exiv2_image_load_string(VALUE self, VALUE string) {
|
58
66
|
__BEGIN
|
data/ext/iptc.cpp
CHANGED
@@ -60,9 +60,15 @@ static bool marshall_value(Exiv2::IptcData &data, const char* key, VALUE value)
|
|
60
60
|
data[key] = Exiv2::DateValue(year, month, day);
|
61
61
|
return true;
|
62
62
|
}
|
63
|
+
case Exiv2::time: {
|
64
|
+
int hour = NUM2INT(rb_funcall(value, rb_intern("hour"), 0));
|
65
|
+
int minute = NUM2INT(rb_funcall(value, rb_intern("min"), 0));
|
66
|
+
int second = NUM2INT(rb_funcall(value, rb_intern("sec"), 0));
|
67
|
+
data[key] = Exiv2::TimeValue(hour, minute, second);
|
68
|
+
return true;
|
69
|
+
}
|
63
70
|
|
64
71
|
case Exiv2::invalid6:
|
65
|
-
case Exiv2::time:
|
66
72
|
case Exiv2::comment:
|
67
73
|
case Exiv2::directory:
|
68
74
|
case Exiv2::lastTypeId:
|
data/ext/marshall.cpp
CHANGED
@@ -98,9 +98,14 @@ VALUE unmarshall_value(const Exiv2::Value& value) {
|
|
98
98
|
Exiv2::DateValue::Date date = date_value->getDate();
|
99
99
|
return rb_funcall(rb_cTime, rb_intern("utc"), 3, INT2FIX(date.year), INT2FIX(date.month), INT2FIX(date.day));
|
100
100
|
}
|
101
|
+
case Exiv2::time: {
|
102
|
+
Exiv2::TimeValue *time_value = dynamic_cast<Exiv2::TimeValue *>(const_cast<Exiv2::Value *>(&value));
|
103
|
+
if(!time_value) return Qnil;
|
104
|
+
Exiv2::TimeValue::Time time = time_value->getTime();
|
105
|
+
return rb_funcall(rb_cTime, rb_intern("utc"), 6, INT2FIX(1970), INT2FIX(1), INT2FIX(1), INT2FIX(time.hour), INT2FIX(time.minute), INT2FIX(time.second));
|
106
|
+
}
|
101
107
|
|
102
108
|
case Exiv2::invalid6:
|
103
|
-
case Exiv2::time:
|
104
109
|
case Exiv2::comment:
|
105
110
|
case Exiv2::directory:
|
106
111
|
case Exiv2::lastTypeId:
|
data/lib/exiv2.rb
CHANGED
@@ -5,17 +5,28 @@ rescue LoadError
|
|
5
5
|
end
|
6
6
|
|
7
7
|
module Exiv2
|
8
|
+
#
|
8
9
|
class Image
|
9
10
|
|
11
|
+
# method [] is used to read exif or iptc data
|
10
12
|
def [](key)
|
11
13
|
return exif[key] if key[0...4] == "Exif"
|
12
14
|
return iptc[key] if key[0...4] == "Iptc"
|
13
15
|
end
|
14
16
|
|
17
|
+
# method []= is used to set exif or iptc data
|
15
18
|
def []=(key, value)
|
16
19
|
return exif[key] = value if key[0...4] == "Exif"
|
17
20
|
return iptc[key] = value if key[0...4] == "Iptc"
|
18
21
|
raise Exiv2::Error, "Unknown key for writing: #{key.inspect}"
|
19
22
|
end
|
23
|
+
|
24
|
+
# clues together Iptc.Application2.DateCreated and Iptc.Application2.TimeCreated if possible
|
25
|
+
def created_at
|
26
|
+
date = iptc["Iptc.Application2.DateCreated"]
|
27
|
+
time = iptc["Iptc.Application2.TimeCreated"]
|
28
|
+
return date unless time
|
29
|
+
Time.utc(date.year, date.month, date.day, time.hour, time.min, time.sec)
|
30
|
+
end
|
20
31
|
end
|
21
32
|
end
|
data/test/image.rb
CHANGED
@@ -205,6 +205,13 @@ class ImageTest < Test::Unit::TestCase
|
|
205
205
|
|
206
206
|
assert @img = Exiv2::Image.new(filename)
|
207
207
|
assert_equal Time.utc(2006, 3, 5), @img["Iptc.Application2.DateCreated"]
|
208
|
+
assert_equal nil, @img["Iptc.Application2.TimeCreated"]
|
209
|
+
assert @img["Iptc.Application2.TimeCreated"] = Time.utc(1970, 1, 1, 15, 43, 23)
|
210
|
+
assert @img.save
|
211
|
+
assert @img = Exiv2::Image.new(filename)
|
212
|
+
assert_equal Time.utc(1970, 1, 1, 15, 43, 23), @img["Iptc.Application2.TimeCreated"]
|
213
|
+
|
214
|
+
assert_equal Time.utc(2006, 3, 5, 15, 43, 23), @img.created_at
|
208
215
|
end
|
209
216
|
end
|
210
217
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-exiv2
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "1.
|
7
|
-
date: 2007-04-
|
6
|
+
version: "1.2"
|
7
|
+
date: 2007-04-12 00:00:00 +04:00
|
8
8
|
summary: Exiv2 (exif image tags handling) library driver
|
9
9
|
require_paths:
|
10
10
|
- lib
|