image_science 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +12 -0
- data/README.txt +12 -9
- data/bench.rb +11 -6
- data/lib/image_science.rb +62 -30
- metadata +10 -10
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
== 1.1.1 / 2007-03-08
|
2
|
+
|
3
|
+
* 5 minor enhancements:
|
4
|
+
* Added error handler that raises with information about what went wrong.
|
5
|
+
* thumbnail is now pure ruby, everything now uses resize.
|
6
|
+
* Produces cleaner JPEG files, with a small cost to file size/speed.
|
7
|
+
* resize now uses Catmull-Rom spline filter for better quality.
|
8
|
+
* resize copies existing ICC Profile to thumbnail, producing better color.
|
9
|
+
* ICC Profile NOT copied for PNG as it seems to be buggy.
|
10
|
+
* 1 bug fix:
|
11
|
+
* Fixed rdoc
|
12
|
+
|
1
13
|
== 1.1.0 / 2007-01-05
|
2
14
|
|
3
15
|
* 3 major enhancements:
|
data/README.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
ImageScience
|
2
|
+
http://seattlerb.rubyforge.org/ImageScience.html
|
2
3
|
http://rubyforge.org/projects/seattlerb
|
3
|
-
http://seattlerb.rubyforge.org/
|
4
4
|
by Ryan Davis
|
5
5
|
|
6
6
|
== DESCRIPTION:
|
@@ -13,18 +13,20 @@ For more information including build steps, see http://seattlerb.rubyforge.org/
|
|
13
13
|
|
14
14
|
== FEATURES/PROBLEMS:
|
15
15
|
|
16
|
-
*
|
17
|
-
* Supports
|
16
|
+
* Glorious graphics manipulation magi... errr, SCIENCE! in less than 200 LoC!
|
17
|
+
* Supports square and proportional thumbnails, as well as arbitrary resizes.
|
18
18
|
* Pretty much any graphics format you could want. No really.
|
19
19
|
|
20
20
|
== SYNOPSYS:
|
21
21
|
|
22
22
|
ImageScience.with_image(file) do |img|
|
23
|
-
img.cropped_thumbnail(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
img.thumbnail(
|
23
|
+
img.cropped_thumbnail(100) do |thumb|
|
24
|
+
thumb.save "#{file}_cropped.png"
|
25
|
+
end
|
26
|
+
|
27
|
+
img.thumbnail(100) do |thumb|
|
28
|
+
thumb.save "#{file}_thumb.png"
|
29
|
+
end
|
28
30
|
end
|
29
31
|
|
30
32
|
== REQUIREMENTS:
|
@@ -36,12 +38,13 @@ For more information including build steps, see http://seattlerb.rubyforge.org/
|
|
36
38
|
|
37
39
|
* Download and install FreeImage. See notes at url above.
|
38
40
|
* sudo gem install -y image_science
|
41
|
+
* see http://seattlerb.rubyforge.org/ImageScience.html for more info.
|
39
42
|
|
40
43
|
== LICENSE:
|
41
44
|
|
42
45
|
(The MIT License)
|
43
46
|
|
44
|
-
Copyright (c) 2006 Ryan Davis, Seattle.rb
|
47
|
+
Copyright (c) 2006-2007 Ryan Davis, Seattle.rb
|
45
48
|
|
46
49
|
Permission is hereby granted, free of charge, to any person obtaining
|
47
50
|
a copy of this software and associated documentation files (the
|
data/bench.rb
CHANGED
@@ -4,7 +4,10 @@ require 'benchmark'
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'image_science'
|
6
6
|
|
7
|
-
|
7
|
+
max = (ARGV.shift || 100).to_i
|
8
|
+
ext = ARGV.shift || "png"
|
9
|
+
|
10
|
+
file = "blah_big.#{ext}"
|
8
11
|
|
9
12
|
if RUBY_PLATFORM =~ /darwin/ then
|
10
13
|
# how fucking cool is this???
|
@@ -14,7 +17,9 @@ else
|
|
14
17
|
abort "You need to plonk down #{file} or buy a mac"
|
15
18
|
end unless test ?f, "#{file}"
|
16
19
|
|
17
|
-
|
20
|
+
ImageScience.with_image(file.sub(/#{ext}$/, 'png')) do |img|
|
21
|
+
img.save(file)
|
22
|
+
end if ext != "png"
|
18
23
|
|
19
24
|
puts "# of iterations = #{max}"
|
20
25
|
Benchmark::bm(20) do |x|
|
@@ -28,7 +33,7 @@ Benchmark::bm(20) do |x|
|
|
28
33
|
for i in 0..max do
|
29
34
|
ImageScience.with_image(file) do |img|
|
30
35
|
img.cropped_thumbnail(100) do |thumb|
|
31
|
-
thumb.save("blah_cropped
|
36
|
+
thumb.save("blah_cropped.#{ext}")
|
32
37
|
end
|
33
38
|
end
|
34
39
|
end
|
@@ -38,7 +43,7 @@ Benchmark::bm(20) do |x|
|
|
38
43
|
for i in 0..max do
|
39
44
|
ImageScience.with_image(file) do |img|
|
40
45
|
img.thumbnail(100) do |thumb|
|
41
|
-
thumb.save("blah_thumb
|
46
|
+
thumb.save("blah_thumb.#{ext}")
|
42
47
|
end
|
43
48
|
end
|
44
49
|
end
|
@@ -48,11 +53,11 @@ Benchmark::bm(20) do |x|
|
|
48
53
|
for i in 0..max do
|
49
54
|
ImageScience.with_image(file) do |img|
|
50
55
|
img.resize(200, 200) do |resize|
|
51
|
-
resize.save("blah_resize
|
56
|
+
resize.save("blah_resize.#{ext}")
|
52
57
|
end
|
53
58
|
end
|
54
59
|
end
|
55
60
|
}
|
56
61
|
end
|
57
62
|
|
58
|
-
# File.unlink(*Dir["blah
|
63
|
+
# File.unlink(*Dir["blah*#{ext}"])
|
data/lib/image_science.rb
CHANGED
@@ -4,25 +4,27 @@ require 'rubygems'
|
|
4
4
|
require 'inline'
|
5
5
|
|
6
6
|
##
|
7
|
-
# Provides a
|
7
|
+
# Provides a clean and simple API to generate thumbnails using
|
8
8
|
# FreeImage as the underlying mechanism.
|
9
9
|
#
|
10
10
|
# For more information or if you have build issues with FreeImage, see
|
11
11
|
# http://seattlerb.rubyforge.org/ImageScience.html
|
12
12
|
|
13
13
|
class ImageScience
|
14
|
-
VERSION = '1.1.
|
14
|
+
VERSION = '1.1.1'
|
15
15
|
|
16
16
|
##
|
17
17
|
# The top-level image loader opens +path+ and then yields the image.
|
18
18
|
|
19
|
-
def self.with_image(path)
|
19
|
+
def self.with_image(path) # :yields: image
|
20
|
+
end
|
20
21
|
|
21
22
|
##
|
22
23
|
# Crops an image to +left+, +top+, +right+, and +bottom+ and then
|
23
24
|
# yields the new image.
|
24
25
|
|
25
|
-
def with_crop(left, top, right, bottom)
|
26
|
+
def with_crop(left, top, right, bottom) # :yields: image
|
27
|
+
end
|
26
28
|
|
27
29
|
##
|
28
30
|
# Returns the width of the image, in pixels.
|
@@ -34,17 +36,31 @@ class ImageScience
|
|
34
36
|
|
35
37
|
def height; end
|
36
38
|
|
39
|
+
##
|
40
|
+
# Saves the image out to +path+. Changing the file extension will
|
41
|
+
# convert the file type to the appropriate format.
|
42
|
+
|
43
|
+
def save(path); end
|
44
|
+
|
37
45
|
##
|
38
46
|
# Resizes the image to +width+ and +height+ using a cubic-bspline
|
39
47
|
# filter and yields the new image.
|
40
48
|
|
41
|
-
def resize(width, height)
|
49
|
+
def resize(width, height) # :yields: image
|
50
|
+
end
|
42
51
|
|
43
52
|
##
|
44
|
-
# Creates a proportional thumbnail of the image scaled so its
|
53
|
+
# Creates a proportional thumbnail of the image scaled so its longest
|
45
54
|
# edge is resized to +size+ and yields the new image.
|
46
55
|
|
47
|
-
def thumbnail(size)
|
56
|
+
def thumbnail(size) # :yields: image
|
57
|
+
w, h = width, height
|
58
|
+
scale = size.to_f / (w > h ? w : h)
|
59
|
+
|
60
|
+
self.resize((w * scale).to_i, (h * scale).to_i) do |image|
|
61
|
+
yield image
|
62
|
+
end
|
63
|
+
end
|
48
64
|
|
49
65
|
##
|
50
66
|
# Creates a square thumbnail of the image cropping the longest edge
|
@@ -84,8 +100,37 @@ class ImageScience
|
|
84
100
|
DATA_PTR(self) = NULL;
|
85
101
|
return Qnil;
|
86
102
|
}
|
103
|
+
|
104
|
+
VALUE wrap_and_yield(FIBITMAP *image, VALUE self, FREE_IMAGE_FORMAT fif) {
|
105
|
+
VALUE klass = fif ? self : CLASS_OF(self);
|
106
|
+
VALUE type = fif ? INT2FIX(fif) : rb_iv_get(self, "@file_type");
|
107
|
+
VALUE obj = Data_Wrap_Struct(klass, NULL, NULL, image);
|
108
|
+
rb_iv_set(obj, "@file_type", type);
|
109
|
+
return rb_ensure(rb_yield, obj, unload, obj);
|
110
|
+
}
|
111
|
+
|
112
|
+
void copy_icc_profile(VALUE self, FIBITMAP *from, FIBITMAP *to) {
|
113
|
+
FREE_IMAGE_FORMAT fif = FIX2INT(rb_iv_get(self, "@file_type"));
|
114
|
+
if (fif != FIF_PNG && FreeImage_FIFSupportsICCProfiles(fif)) {
|
115
|
+
FIICCPROFILE *profile = FreeImage_GetICCProfile(from);
|
116
|
+
if (profile && profile->data) {
|
117
|
+
FreeImage_CreateICCProfile(to, profile->data, profile->size);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
}
|
121
|
+
END
|
122
|
+
|
123
|
+
builder.prefix <<-"END"
|
124
|
+
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
|
125
|
+
rb_raise(rb_eRuntimeError,
|
126
|
+
"FreeImage exception for type %s: %s",
|
127
|
+
(fif == FIF_UNKNOWN) ? "???" : FreeImage_GetFormatFromFIF(fif),
|
128
|
+
message);
|
129
|
+
}
|
87
130
|
END
|
88
131
|
|
132
|
+
builder.add_to_init "FreeImage_SetOutputMessage(FreeImageErrorHandler);"
|
133
|
+
|
89
134
|
builder.c_singleton <<-"END"
|
90
135
|
VALUE with_image(char * input) {
|
91
136
|
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
@@ -95,10 +140,9 @@ class ImageScience
|
|
95
140
|
if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
|
96
141
|
FIBITMAP *bitmap;
|
97
142
|
VALUE result = Qnil;
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
result = rb_ensure(rb_yield, obj, unload, obj);
|
143
|
+
int flags = fif == FIF_JPEG ? JPEG_ACCURATE : 0;
|
144
|
+
if (bitmap = FreeImage_Load(fif, input, flags)) {
|
145
|
+
result = wrap_and_yield(bitmap, self, fif);
|
102
146
|
}
|
103
147
|
return result;
|
104
148
|
}
|
@@ -113,8 +157,8 @@ class ImageScience
|
|
113
157
|
GET_BITMAP(bitmap);
|
114
158
|
|
115
159
|
if (copy = FreeImage_Copy(bitmap, l, t, r, b)) {
|
116
|
-
|
117
|
-
result =
|
160
|
+
copy_icc_profile(self, bitmap, copy);
|
161
|
+
result = wrap_and_yield(copy, self, 0);
|
118
162
|
}
|
119
163
|
return result;
|
120
164
|
}
|
@@ -136,21 +180,12 @@ class ImageScience
|
|
136
180
|
}
|
137
181
|
END
|
138
182
|
|
139
|
-
builder.c <<-"END"
|
140
|
-
VALUE thumbnail(int size) {
|
141
|
-
GET_BITMAP(bitmap);
|
142
|
-
FIBITMAP *image = FreeImage_MakeThumbnail(bitmap, size, TRUE);
|
143
|
-
VALUE obj = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, image);
|
144
|
-
return rb_ensure(rb_yield, obj, unload, obj);
|
145
|
-
}
|
146
|
-
END
|
147
|
-
|
148
183
|
builder.c <<-"END"
|
149
184
|
VALUE resize(int w, int h) {
|
150
185
|
GET_BITMAP(bitmap);
|
151
|
-
FIBITMAP *image = FreeImage_Rescale(bitmap, w, h,
|
152
|
-
|
153
|
-
return
|
186
|
+
FIBITMAP *image = FreeImage_Rescale(bitmap, w, h, FILTER_CATMULLROM);
|
187
|
+
copy_icc_profile(self, bitmap, image);
|
188
|
+
return wrap_and_yield(image, self, 0);
|
154
189
|
}
|
155
190
|
END
|
156
191
|
|
@@ -160,11 +195,8 @@ class ImageScience
|
|
160
195
|
if (fif == FIF_UNKNOWN) fif = FIX2INT(rb_iv_get(self, "@file_type"));
|
161
196
|
if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsWriting(fif)) {
|
162
197
|
GET_BITMAP(bitmap);
|
163
|
-
|
164
|
-
|
165
|
-
return Qtrue;
|
166
|
-
}
|
167
|
-
return Qfalse;
|
198
|
+
int flags = fif == FIF_JPEG ? JPEG_QUALITYSUPERB : 0;
|
199
|
+
return FreeImage_Save(fif, bitmap, output, flags) ? Qtrue : Qfalse;
|
168
200
|
}
|
169
201
|
rb_raise(rb_eTypeError, "Unknown file format");
|
170
202
|
}
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.0.
|
2
|
+
rubygems_version: 0.9.0.9
|
3
3
|
specification_version: 1
|
4
4
|
name: image_science
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.1.
|
7
|
-
date: 2007-
|
6
|
+
version: 1.1.1
|
7
|
+
date: 2007-03-08 00:00:00 -08:00
|
8
8
|
summary: ImageScience is a clean and happy Ruby library that generates thumbnails -- and kicks the living crap out of RMagick.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: ryand-ruby@zenspider.com
|
12
|
-
homepage: http://rubyforge.org/
|
12
|
+
homepage: http://seattlerb.rubyforge.org/ImageScience.html
|
13
13
|
rubyforge_project: seattlerb
|
14
14
|
description: ImageScience is a clean and happy Ruby library that generates thumbnails -- and kicks the living crap out of RMagick. Oh, and it doesn't leak memory like a sieve. :) For more information including build steps, see http://seattlerb.rubyforge.org/
|
15
15
|
autorequire:
|
@@ -49,20 +49,20 @@ requirements: []
|
|
49
49
|
|
50
50
|
dependencies:
|
51
51
|
- !ruby/object:Gem::Dependency
|
52
|
-
name:
|
52
|
+
name: RubyInline
|
53
53
|
version_requirement:
|
54
54
|
version_requirements: !ruby/object:Gem::Version::Requirement
|
55
55
|
requirements:
|
56
|
-
- - "
|
56
|
+
- - ">"
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version:
|
58
|
+
version: 0.0.0
|
59
59
|
version:
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
|
-
name:
|
61
|
+
name: hoe
|
62
62
|
version_requirement:
|
63
63
|
version_requirements: !ruby/object:Gem::Version::Requirement
|
64
64
|
requirements:
|
65
|
-
- - "
|
65
|
+
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version:
|
67
|
+
version: 1.2.0
|
68
68
|
version:
|