image_science 1.1.0 → 1.1.1
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.
- 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:
|