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.
Files changed (5) hide show
  1. data/History.txt +12 -0
  2. data/README.txt +12 -9
  3. data/bench.rb +11 -6
  4. data/lib/image_science.rb +62 -30
  5. 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
- * 93 glorious lines of graphics manipulation magi... errr, SCIENCE!
17
- * Supports both square and proportional thumbnails.
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("#{file}_cropped.png", 100)
24
- end
25
-
26
- ImageScience.with_image(file) do |img|
27
- img.thumbnail("#{file}_thumb.png", 100)
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
- file = "blah_big.png"
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
- max = (ARGV.shift || 100).to_i
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.png")
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.png")
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.png")
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*png"])
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 simple and clean API to generate thumbnails using
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.0'
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); end # :yields: image
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); end # :yields: image
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); end # :yields: image
49
+ def resize(width, height) # :yields: image
50
+ end
42
51
 
43
52
  ##
44
- # Creates a proportional thumbnail of the image scaled so its widest
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); end # :yields: image
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
- if (bitmap = FreeImage_Load(fif, input, 0)) {
99
- VALUE obj = Data_Wrap_Struct(self, NULL, NULL, bitmap);
100
- rb_iv_set(obj, "@file_type", INT2FIX(fif));
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
- VALUE obj = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, copy);
117
- result = rb_ensure(rb_yield, obj, unload, obj);
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, FILTER_BSPLINE);
152
- VALUE obj = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, image);
153
- return rb_ensure(rb_yield, obj, unload, obj);
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
- if (FreeImage_Save(fif, bitmap, output, 0)) {
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.8
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.0
7
- date: 2007-01-05 00:00:00 -08:00
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/projects/seattlerb
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: hoe
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: 1.1.6
58
+ version: 0.0.0
59
59
  version:
60
60
  - !ruby/object:Gem::Dependency
61
- name: RubyInline
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: 0.0.0
67
+ version: 1.2.0
68
68
  version: