g1nn13-image_science 1.2.5 → 1.2.6

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.tar.gz.sig ADDED
Binary file
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ === 1.2.6 / 2010-05-26
2
+
3
+ * Now based on ImageScience 1.2.1
4
+ * Added new method resize_with_crop
5
+
1
6
  === 1.2.5 / 2010-01-26
2
7
 
3
8
  * 1 tweak
data/README.txt CHANGED
@@ -11,6 +11,11 @@ g1nn13 fork changes:
11
11
  * added buffer() method to get image buffer for writing (to Amazon S3)
12
12
  * added fit_within() method to resize an image to fit within a specified
13
13
  height and width without changing the image's aspect ratio
14
+ * added resize_with_crop() to resize and crop images where the
15
+ target aspect ratio differs from the original aspect ratio. This is
16
+ for converting portrait to landscape and landscape to portrait.
17
+
18
+
14
19
 
15
20
  ImageScience is a clean and happy Ruby library that generates
16
21
  thumbnails -- and kicks the living crap out of RMagick. Oh, and it
data/lib/image_science.rb CHANGED
@@ -9,9 +9,11 @@ require 'inline'
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
+ #
13
+ # Based on ImageScience 1.2.1
12
14
 
13
15
  class ImageScience
14
- VERSION = '1.2.5'
16
+ VERSION = '1.2.6'
15
17
 
16
18
  ##
17
19
  # The top-level image loader opens +path+ and then yields the image.
@@ -55,6 +57,79 @@ class ImageScience
55
57
  def buffer(extension) # :yields: image
56
58
  end
57
59
 
60
+
61
+ ##
62
+ # Resizes an image to the specified size without stretching or
63
+ # compressing the original. If the aspect ratio of the new height/width
64
+ # does not match the aspect ratio of the original (as when converting
65
+ # portrait to landscape or landscape to portrait), the resulting
66
+ # image will be cropped. Cropping preserves the center of the image,
67
+ # with content trimmed evenly from the top and bottom and/or left and
68
+ # right edges of the image. This can cause some less than ideal
69
+ # conversions. For example, converting a portrait to a landscape can
70
+ # result in the portrait's head being cut off.
71
+
72
+ def resize_with_crop(width, height, &block)
73
+
74
+ # ---------------------------------------------------------------
75
+ # We want to adjust both height and width by the same ratio,
76
+ # so the image is not stretched. Adjust everything by the
77
+ # larger ratio, so that portrait to landscape and landscape
78
+ # to portrait transformations come out right.
79
+ # ---------------------------------------------------------------
80
+ src2target_height_ratio = height.to_f / self.height
81
+ src2target_width_ratio = width.to_f / self.width
82
+ height_ratio_is_larger = src2target_height_ratio > src2target_width_ratio
83
+ if height_ratio_is_larger
84
+ target_height = (self.height * src2target_height_ratio).round
85
+ target_width = (self.width * src2target_height_ratio).round
86
+ else
87
+ target_height = (self.height * src2target_width_ratio).round
88
+ target_width = (self.width * src2target_width_ratio).round
89
+ end
90
+
91
+ # ---------------------------------------------------------------
92
+ # Create a version of this image whose longest
93
+ # side is equal to max_dimension. We'll add two
94
+ # to this value, since floating point arithmetic
95
+ # often produces values 1-2 pixels short of what we want.
96
+ # ---------------------------------------------------------------
97
+ max_dimension = (target_height > target_width ?
98
+ target_height : target_width)
99
+
100
+ self.thumbnail(max_dimension + 2) do |img1|
101
+ top, left = 0, 0
102
+ top = (img1.height - height) / 2 unless img1.height < height
103
+ left = (img1.width - width) / 2 unless img1.width < width
104
+ right = width + left
105
+ bottom = height + top
106
+
107
+ # ---------------------------------------------------------------
108
+ # Crop the resized image evenly at top/bottom, left/right,
109
+ # so that we preserve the center.
110
+ # ---------------------------------------------------------------
111
+ result = img1.with_crop(left, top, right, bottom) do |img2|
112
+ if block_given?
113
+ yield img2
114
+ else
115
+ return img2
116
+ end
117
+ end
118
+
119
+ if result.nil?
120
+ message = "Crop/resize failed... is some dimension is out of bounds?"
121
+ message += "Original Height = #{self.height}, Width = #{self.width}"
122
+ message += "Target Height = #{height}, Width = #{width}"
123
+ message += "Actual Height = #{self.height}, Width = #{self.width}"
124
+ message += "Left=#{left}, Top=#{top}, Right=#{right}, Bottom=#{bottom}"
125
+ raise message
126
+ end
127
+
128
+
129
+ end
130
+ end
131
+
132
+
58
133
  ##
59
134
  # Resizes the image to +width+ and +height+ using a cubic-bspline
60
135
  # filter and yields the new image.
@@ -121,6 +196,25 @@ class ImageScience
121
196
  end
122
197
  end
123
198
 
199
+ ##
200
+ # Creates a square thumbnail of the image cropping the longest edge
201
+ # to match the shortest edge, resizes to +size+, and yields the new
202
+ # image.
203
+
204
+ def cropped_to_fit(width, height) # :yields: image
205
+ w, h = width, height
206
+ l, t, r, b, half = 0, 0, w, h, (w - h).abs / 2
207
+
208
+ l, r = half, half + h if w > h
209
+ t, b = half, half + w if h > w
210
+
211
+ with_crop(l, t, r, b) do |img|
212
+ img.thumbnail(size) do |thumb|
213
+ yield thumb
214
+ end
215
+ end
216
+ end
217
+
124
218
  inline do |builder|
125
219
  if test ?d, "/opt/local" then
126
220
  builder.add_compile_flags "-I/opt/local/include"
@@ -138,249 +232,190 @@ class ImageScience
138
232
  builder.include '"FreeImage.h"'
139
233
 
140
234
  builder.prefix <<-"END"
141
- #define GET_BITMAP(name) Data_Get_Struct(self, FIBITMAP, (name)); if (!(name)) rb_raise(rb_eTypeError, "Bitmap has already been freed");
142
- END
235
+ #define GET_BITMAP(name) Data_Get_Struct(self, FIBITMAP, (name)); if (!(name)) rb_raise(rb_eTypeError, "Bitmap has already been freed");
236
+ END
143
237
 
144
238
  builder.prefix <<-"END"
145
- VALUE unload(VALUE self) {
146
- FIBITMAP *bitmap;
147
- GET_BITMAP(bitmap);
239
+ VALUE unload(VALUE self) {
240
+ FIBITMAP *bitmap;
241
+ GET_BITMAP(bitmap);
148
242
 
149
- FreeImage_Unload(bitmap);
150
- DATA_PTR(self) = NULL;
151
- return Qnil;
152
- }
153
- END
243
+ FreeImage_Unload(bitmap);
244
+ DATA_PTR(self) = NULL;
245
+ return Qnil;
246
+ }
247
+ END
154
248
 
155
249
  builder.prefix <<-"END"
156
- VALUE wrap_and_yield(FIBITMAP *image, VALUE self, FREE_IMAGE_FORMAT fif) {
157
- unsigned int self_is_class = rb_type(self) == T_CLASS;
158
- VALUE klass = self_is_class ? self : CLASS_OF(self);
159
- VALUE type = self_is_class ? INT2FIX(fif) : rb_iv_get(self, "@file_type");
160
- VALUE obj = Data_Wrap_Struct(klass, NULL, NULL, image);
161
- rb_iv_set(obj, "@file_type", type);
162
- return rb_ensure(rb_yield, obj, unload, obj);
163
- }
164
- END
250
+ VALUE wrap_and_yield(FIBITMAP *image, VALUE self, FREE_IMAGE_FORMAT fif) {
251
+ unsigned int self_is_class = rb_type(self) == T_CLASS;
252
+ VALUE klass = self_is_class ? self : CLASS_OF(self);
253
+ VALUE type = self_is_class ? INT2FIX(fif) : rb_iv_get(self, "@file_type");
254
+ VALUE obj = Data_Wrap_Struct(klass, NULL, NULL, image);
255
+ rb_iv_set(obj, "@file_type", type);
256
+ return rb_ensure(rb_yield, obj, unload, obj);
257
+ }
258
+ END
165
259
 
166
260
  builder.prefix <<-"END"
167
- void copy_icc_profile(VALUE self, FIBITMAP *from, FIBITMAP *to) {
168
- FREE_IMAGE_FORMAT fif = FIX2INT(rb_iv_get(self, "@file_type"));
169
- if (fif != FIF_PNG && FreeImage_FIFSupportsICCProfiles(fif)) {
170
- FIICCPROFILE *profile = FreeImage_GetICCProfile(from);
171
- if (profile && profile->data) {
172
- FreeImage_CreateICCProfile(to, profile->data, profile->size);
173
- }
174
- }
175
- }
176
- END
261
+ void copy_icc_profile(VALUE self, FIBITMAP *from, FIBITMAP *to) {
262
+ FREE_IMAGE_FORMAT fif = FIX2INT(rb_iv_get(self, "@file_type"));
263
+ if (fif != FIF_PNG && FreeImage_FIFSupportsICCProfiles(fif)) {
264
+ FIICCPROFILE *profile = FreeImage_GetICCProfile(from);
265
+ if (profile && profile->data) {
266
+ FreeImage_CreateICCProfile(to, profile->data, profile->size);
267
+ }
268
+ }
269
+ }
270
+ END
177
271
 
178
272
  builder.prefix <<-"END"
179
- void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
180
- rb_raise(rb_eRuntimeError,
181
- "FreeImage exception for type %s: %s",
182
- (fif == FIF_UNKNOWN) ? "???" : FreeImage_GetFormatFromFIF(fif),
183
- message);
184
- }
185
- END
273
+ void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) {
274
+ rb_raise(rb_eRuntimeError,
275
+ "FreeImage exception for type %s: %s",
276
+ (fif == FIF_UNKNOWN) ? "???" : FreeImage_GetFormatFromFIF(fif),
277
+ message);
278
+ }
279
+ END
186
280
 
187
281
  builder.add_to_init "FreeImage_SetOutputMessage(FreeImageErrorHandler);"
188
282
 
189
283
  builder.c_singleton <<-"END"
190
- VALUE with_image(char * input) {
191
- FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
192
- int flags;
193
-
194
- fif = FreeImage_GetFileType(input, 0);
195
- if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(input);
196
- if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
197
- FIBITMAP *bitmap;
198
- VALUE result = Qnil;
199
- flags = fif == FIF_JPEG ? JPEG_ACCURATE : 0;
200
- if (bitmap = FreeImage_Load(fif, input, flags)) {
201
- FITAG *tagValue = NULL;
202
- FreeImage_GetMetadata(FIMD_EXIF_MAIN, bitmap, "Orientation", &tagValue);
203
- switch (tagValue == NULL ? 0 : *((short *) FreeImage_GetTagValue(tagValue))) {
204
- case 6:
205
- bitmap = FreeImage_RotateClassic(bitmap, 270);
206
- break;
207
- case 3:
208
- bitmap = FreeImage_RotateClassic(bitmap, 180);
209
- break;
210
- case 8:
211
- bitmap = FreeImage_RotateClassic(bitmap, 90);
212
- break;
213
- default:
214
- break;
215
- }
216
-
217
- result = wrap_and_yield(bitmap, self, fif);
218
- }
219
- return result;
220
- }
221
- rb_raise(rb_eTypeError, "Unknown file format");
222
- }
223
- END
284
+ VALUE with_image(char * input) {
285
+ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
286
+ int flags;
287
+
288
+ fif = FreeImage_GetFileType(input, 0);
289
+ if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(input);
290
+ if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
291
+ FIBITMAP *bitmap;
292
+ VALUE result = Qnil;
293
+ flags = fif == FIF_JPEG ? JPEG_ACCURATE : 0;
294
+ if (bitmap = FreeImage_Load(fif, input, flags)) {
295
+ FITAG *tagValue = NULL;
296
+ FreeImage_GetMetadata(FIMD_EXIF_MAIN, bitmap, "Orientation", &tagValue);
297
+ switch (tagValue == NULL ? 0 : *((short *) FreeImage_GetTagValue(tagValue))) {
298
+ case 6:
299
+ bitmap = FreeImage_RotateClassic(bitmap, 270);
300
+ break;
301
+ case 3:
302
+ bitmap = FreeImage_RotateClassic(bitmap, 180);
303
+ break;
304
+ case 8:
305
+ bitmap = FreeImage_RotateClassic(bitmap, 90);
306
+ break;
307
+ default:
308
+ break;
309
+ }
310
+
311
+ result = wrap_and_yield(bitmap, self, fif);
312
+ }
313
+ return result;
314
+ }
315
+ rb_raise(rb_eTypeError, "Unknown file format");
316
+ }
317
+ END
224
318
 
225
319
  builder.c_singleton <<-"END"
226
- VALUE with_image_from_memory(VALUE image_data) {
227
- FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
228
-
229
- Check_Type(image_data, T_STRING);
230
- BYTE *image_data_ptr = (BYTE*)RSTRING_PTR(image_data);
231
- DWORD image_data_length = RSTRING_LEN(image_data);
232
- FIMEMORY *stream = FreeImage_OpenMemory(image_data_ptr, image_data_length);
233
-
234
- if (NULL == stream) {
235
- rb_raise(rb_eTypeError, "Unable to open image_data");
236
- }
237
-
238
- fif = FreeImage_GetFileTypeFromMemory(stream, 0);
239
- if ((fif == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading(fif)) {
240
- rb_raise(rb_eTypeError, "Unknown file format");
241
- }
242
-
243
- FIBITMAP *bitmap = NULL;
244
- VALUE result = Qnil;
245
- int flags = fif == FIF_JPEG ? JPEG_ACCURATE : 0;
246
- bitmap = FreeImage_LoadFromMemory(fif, stream, flags);
247
- FreeImage_CloseMemory(stream);
248
- if (bitmap) {
249
- result = wrap_and_yield(bitmap, self, fif);
250
- }
251
- return result;
252
- }
253
- END
320
+ VALUE with_image_from_memory(VALUE image_data) {
321
+ FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
322
+
323
+ Check_Type(image_data, T_STRING);
324
+ BYTE *image_data_ptr = (BYTE*)RSTRING_PTR(image_data);
325
+ DWORD image_data_length = RSTRING_LEN(image_data);
326
+ FIMEMORY *stream = FreeImage_OpenMemory(image_data_ptr, image_data_length);
327
+
328
+ if (NULL == stream) {
329
+ rb_raise(rb_eTypeError, "Unable to open image_data");
330
+ }
331
+
332
+ fif = FreeImage_GetFileTypeFromMemory(stream, 0);
333
+ if ((fif == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading(fif)) {
334
+ rb_raise(rb_eTypeError, "Unknown file format");
335
+ }
336
+
337
+ FIBITMAP *bitmap = NULL;
338
+ VALUE result = Qnil;
339
+ int flags = fif == FIF_JPEG ? JPEG_ACCURATE : 0;
340
+ bitmap = FreeImage_LoadFromMemory(fif, stream, flags);
341
+ FreeImage_CloseMemory(stream);
342
+ if (bitmap) {
343
+ result = wrap_and_yield(bitmap, self, fif);
344
+ }
345
+ return result;
346
+ }
347
+ END
254
348
 
255
349
  builder.c <<-"END"
256
- VALUE with_crop(int l, int t, int r, int b) {
257
- FIBITMAP *copy, *bitmap;
258
- VALUE result = Qnil;
259
- GET_BITMAP(bitmap);
260
-
261
- if (copy = FreeImage_Copy(bitmap, l, t, r, b)) {
262
- copy_icc_profile(self, bitmap, copy);
263
- result = wrap_and_yield(copy, self, 0);
264
- }
265
- return result;
266
- }
267
- END
350
+ VALUE with_crop(int l, int t, int r, int b) {
351
+ FIBITMAP *copy, *bitmap;
352
+ VALUE result = Qnil;
353
+ GET_BITMAP(bitmap);
354
+
355
+ if (copy = FreeImage_Copy(bitmap, l, t, r, b)) {
356
+ copy_icc_profile(self, bitmap, copy);
357
+ result = wrap_and_yield(copy, self, 0);
358
+ }
359
+ return result;
360
+ }
361
+ END
268
362
 
269
363
  builder.c <<-"END"
270
- int height() {
271
- FIBITMAP *bitmap;
272
- GET_BITMAP(bitmap);
364
+ int height() {
365
+ FIBITMAP *bitmap;
366
+ GET_BITMAP(bitmap);
273
367
 
274
- return FreeImage_GetHeight(bitmap);
275
- }
276
- END
368
+ return FreeImage_GetHeight(bitmap);
369
+ }
370
+ END
277
371
 
278
372
  builder.c <<-"END"
279
- int width() {
280
- FIBITMAP *bitmap;
281
- GET_BITMAP(bitmap);
373
+ int width() {
374
+ FIBITMAP *bitmap;
375
+ GET_BITMAP(bitmap);
282
376
 
283
- return FreeImage_GetWidth(bitmap);
284
- }
285
- END
286
-
287
- builder.c <<-"END"
288
- VALUE resize(long w, long h) {
289
- FIBITMAP *bitmap, *image;
290
- if (w <= 0) rb_raise(rb_eArgError, "Width <= 0");
291
- if (h <= 0) rb_raise(rb_eArgError, "Height <= 0");
292
- GET_BITMAP(bitmap);
293
- image = FreeImage_Rescale(bitmap, w, h, FILTER_CATMULLROM);
294
- if (image) {
295
- copy_icc_profile(self, bitmap, image);
296
- return wrap_and_yield(image, self, 0);
297
- }
298
- return Qnil;
299
- }
300
- END
377
+ return FreeImage_GetWidth(bitmap);
378
+ }
379
+ END
301
380
 
302
381
  builder.c <<-"END"
303
- VALUE save(char * output) {
304
- int flags;
305
- FIBITMAP *bitmap;
306
- FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(output);
307
- if (fif == FIF_UNKNOWN) fif = FIX2INT(rb_iv_get(self, "@file_type"));
308
- if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsWriting(fif)) {
309
- GET_BITMAP(bitmap);
310
- flags = fif == FIF_JPEG ? JPEG_QUALITYSUPERB : 0;
311
- BOOL result = 0, unload = 0;
312
-
313
- if (fif == FIF_PNG) FreeImage_DestroyICCProfile(bitmap);
314
- if (fif == FIF_JPEG && FreeImage_GetBPP(bitmap) != 24)
315
- bitmap = FreeImage_ConvertTo24Bits(bitmap), unload = 1; // sue me
316
-
317
- result = FreeImage_Save(fif, bitmap, output, flags);
318
-
319
- if (unload) FreeImage_Unload(bitmap);
320
-
321
- return result ? Qtrue : Qfalse;
322
- }
323
- rb_raise(rb_eTypeError, "Unknown file format");
324
- }
325
- END
382
+ VALUE resize(long w, long h) {
383
+ FIBITMAP *bitmap, *image;
384
+ if (w <= 0) rb_raise(rb_eArgError, "Width <= 0");
385
+ if (h <= 0) rb_raise(rb_eArgError, "Height <= 0");
386
+ GET_BITMAP(bitmap);
387
+ image = FreeImage_Rescale(bitmap, w, h, FILTER_CATMULLROM);
388
+ if (image) {
389
+ copy_icc_profile(self, bitmap, image);
390
+ return wrap_and_yield(image, self, 0);
391
+ }
392
+ return Qnil;
393
+ }
394
+ END
326
395
 
327
396
  builder.c <<-"END"
328
- VALUE buffer(char * extension) {
329
- VALUE str;
330
- int flags;
331
- FIBITMAP *bitmap;
332
- FIMEMORY *mem = NULL;
333
- long file_size;
334
- BYTE *mem_buffer = NULL;
335
- DWORD size_in_bytes = 0;
336
- char message[1024];
337
- FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(extension);
338
-
339
- if (fif == FIF_UNKNOWN) {
340
- fif = FIX2INT(rb_iv_get(self, "@file_type"));
341
- }
342
- if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsWriting(fif)) {
343
- GET_BITMAP(bitmap);
344
- flags = (fif == FIF_JPEG ? JPEG_QUALITYSUPERB : 0);
345
- BOOL result = 0, unload = 0;
346
- FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(extension);
347
-
348
- // create a memory stream and save to it
349
- bitmap = FreeImage_ConvertTo24Bits(bitmap);
350
- unload = 1;
351
- mem = FreeImage_OpenMemory(0,0);
352
- result = FreeImage_SaveToMemory(fif, bitmap, mem, flags);
353
-
354
- // get the buffer from the memory stream
355
- FreeImage_AcquireMemory(mem, &mem_buffer, &size_in_bytes);
356
-
357
- // convert to ruby string
358
- str = rb_str_new((char *) mem_buffer, size_in_bytes);
359
-
360
- // clean up
361
- if (unload) FreeImage_Unload(bitmap);
362
- FreeImage_CloseMemory(mem);
363
-
364
- // yield the string, or return it
365
- if (rb_block_given_p()) {
366
- if (result && str) {
367
- rb_yield(str);
368
- } else {
369
- rb_yield(Qnil);
370
- }
371
- }
372
- if (result && str) {
373
- return str;
374
- } else {
375
- return Qnil;
376
- }
377
- }
378
- snprintf(message,
379
- 1023,
380
- "Unknown file format: %s",
381
- extension);
382
- rb_raise(rb_eTypeError, message);
383
- }
384
- END
397
+ VALUE save(char * output) {
398
+ int flags;
399
+ FIBITMAP *bitmap;
400
+ FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(output);
401
+ if (fif == FIF_UNKNOWN) fif = FIX2INT(rb_iv_get(self, "@file_type"));
402
+ if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsWriting(fif)) {
403
+ GET_BITMAP(bitmap);
404
+ flags = fif == FIF_JPEG ? JPEG_QUALITYSUPERB : 0;
405
+ BOOL result = 0, unload = 0;
406
+
407
+ if (fif == FIF_PNG) FreeImage_DestroyICCProfile(bitmap);
408
+ if (fif == FIF_JPEG && FreeImage_GetBPP(bitmap) != 24)
409
+ bitmap = FreeImage_ConvertTo24Bits(bitmap), unload = 1; // sue me
410
+
411
+ result = FreeImage_Save(fif, bitmap, output, flags);
412
+
413
+ if (unload) FreeImage_Unload(bitmap);
414
+
415
+ return result ? Qtrue : Qfalse;
416
+ }
417
+ rb_raise(rb_eTypeError, "Unknown file format");
418
+ }
419
+ END
385
420
  end
386
421
  end
@@ -61,11 +61,11 @@ class TestImageScience < MiniTest::Unit::TestCase
61
61
 
62
62
  def test_class_with_image_missing_with_img_extension
63
63
 
64
- # assert_raises RuntimeError do
64
+ assert_raises RuntimeError do
65
65
  assert_nil ImageScience.with_image("nope#{@pix}") do |img|
66
66
  flunk
67
67
  end
68
- # end
68
+ end
69
69
  end
70
70
 
71
71
  def test_class_with_image_from_memory
@@ -114,7 +114,10 @@ class TestImageScience < MiniTest::Unit::TestCase
114
114
  def test_buffer_return
115
115
  ImageScience.with_image @pix do |img|
116
116
  img.resize(25, 25) do |thumb|
117
- assert thumb.buffer('.jpg')
117
+ # assert thumb.buffer('.jpg')
118
+ thumb.buffer('.jpg') do |buffer|
119
+ assert buffer
120
+ end
118
121
  end
119
122
  end
120
123
  end
@@ -315,4 +318,23 @@ class TestImageScience < MiniTest::Unit::TestCase
315
318
  end
316
319
  }
317
320
  end
321
+
322
+ def test_resize_with_crop
323
+ images = [@pix, @bearry, @biggie, @godzilla, @landscape, @portrait]
324
+ heights = [50, 450]
325
+ widths = [80, 725]
326
+ images.each do |image_file|
327
+ ImageScience.with_image(image_file) do |img|
328
+ heights.each_with_index do |height, index|
329
+ width = widths[index]
330
+ img.resize_with_crop(width, height) do |resized_image|
331
+ assert(resized_image.nil? == false)
332
+ assert_equal(height, resized_image.height)
333
+ assert_equal(width, resized_image.width)
334
+ end
335
+ end
336
+ end
337
+ end
338
+ end
339
+
318
340
  end
metadata CHANGED
@@ -1,103 +1,152 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: g1nn13-image_science
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 2
8
+ - 6
9
+ version: 1.2.6
5
10
  platform: ruby
6
11
  authors:
7
12
  - jim nist
8
13
  autorequire:
9
14
  bindir: bin
10
- cert_chain: []
15
+ cert_chain:
16
+ - |
17
+ -----BEGIN CERTIFICATE-----
18
+ MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQwwCgYDVQQDDANqaW0x
19
+ HDAaBgoJkiaJk/IsZAEZFgxob3RlbGljb3B0ZXIxEzARBgoJkiaJk/IsZAEZFgNj
20
+ b20wHhcNMTAwNTI2MTYwNTM5WhcNMTEwNTI2MTYwNTM5WjBBMQwwCgYDVQQDDANq
21
+ aW0xHDAaBgoJkiaJk/IsZAEZFgxob3RlbGljb3B0ZXIxEzARBgoJkiaJk/IsZAEZ
22
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzbudw4TyxDTEj
23
+ /UMsEt2LFWmDiEKmyKHnHiPdjINn/wY8yYw1oujRj2c2iXlaon68u8G+1qacfyd0
24
+ gpHPFQfqBFKLDtPgPffzAkY8fvW4MgjRYFcymdpiVGpHCoTgvhO9Efsrd/d8Ja4n
25
+ oeEPNHdXr/bHwLhgIAup6JYQAZSL1DY77co3rbvY1xqovbc6tg/M7cbXPp1lmONS
26
+ XwIHPWjsl3mL1IWEQPt2dmPy6ZLYliKowdGlDUblupXuVlO9cS67yf3MlJp874mY
27
+ yH1qAwSK/Toe2L39TTi/Hyx6HMFECTmkLUT/4X2z6zWUlK0e5Hr8ViBCzh2BTOyO
28
+ jojoYo7tAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
29
+ BBQ1LMdE7DCtf+7x6tJAqGRMKMtVXDANBgkqhkiG9w0BAQUFAAOCAQEAIu7ygDoV
30
+ g5wdi3wWR//1yK86vQe36luyolo3GL+Z0FmIIA+tdAPZtMAlnFasOSfLVDdkxb3O
31
+ J2MLyH5KHY5asc27J+Y/zUofGWj5JgQZIg+gAGcDuq94kr4NXgFTL4khE3zhI4uH
32
+ 65+zkHrnetmZPilpTbFjzvM1SfuzrU9t+ugEu7R1vmAQdhdcgSwXr0MYPy5oZWgQ
33
+ eayeSBRjd6tzceXRmaZYWDH2wra509l63UgJw6dsNgWzQH1XQ1XzqJXX/J8FRgDI
34
+ n3ugwImcS/YB+ZQ3TQ3uKX8E5Ikos7YH0Pc/WRQnMzcjBmNtx7GsV9MC9Qx/i+YC
35
+ UHHftgnvI+YPGw==
36
+ -----END CERTIFICATE-----
11
37
 
12
- date: 2010-01-26 00:00:00 -05:00
38
+ date: 2010-05-26 00:00:00 -04:00
13
39
  default_executable:
14
40
  dependencies:
15
41
  - !ruby/object:Gem::Dependency
16
42
  name: hoe
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
43
+ prerelease: false
44
+ requirement: &id001 !ruby/object:Gem::Requirement
20
45
  requirements:
21
46
  - - ">="
22
47
  - !ruby/object:Gem::Version
48
+ segments:
49
+ - 2
50
+ - 5
51
+ - 0
23
52
  version: 2.5.0
24
- version:
25
- - !ruby/object:Gem::Dependency
26
- name: gemcutter
27
53
  type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 0.3.0
34
- version:
54
+ version_requirements: *id001
35
55
  - !ruby/object:Gem::Dependency
36
56
  name: gemcutter
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
57
+ prerelease: false
58
+ requirement: &id002 !ruby/object:Gem::Requirement
40
59
  requirements:
41
60
  - - ">="
42
61
  - !ruby/object:Gem::Version
62
+ segments:
63
+ - 0
64
+ - 3
65
+ - 0
43
66
  version: 0.3.0
44
- version:
67
+ type: :runtime
68
+ version_requirements: *id002
45
69
  - !ruby/object:Gem::Dependency
46
70
  name: hoe-doofus
47
- type: :development
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
71
+ prerelease: false
72
+ requirement: &id003 !ruby/object:Gem::Requirement
50
73
  requirements:
51
74
  - - ">="
52
75
  - !ruby/object:Gem::Version
76
+ segments:
77
+ - 1
78
+ - 0
79
+ - 0
53
80
  version: 1.0.0
54
- version:
81
+ type: :development
82
+ version_requirements: *id003
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: hoe-git
57
- type: :development
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
85
+ prerelease: false
86
+ requirement: &id004 !ruby/object:Gem::Requirement
60
87
  requirements:
61
88
  - - ">="
62
89
  - !ruby/object:Gem::Version
90
+ segments:
91
+ - 1
92
+ - 3
93
+ - 0
63
94
  version: 1.3.0
64
- version:
95
+ type: :development
96
+ version_requirements: *id004
65
97
  - !ruby/object:Gem::Dependency
66
98
  name: hoe-telicopter
67
- type: :development
68
- version_requirement:
69
- version_requirements: !ruby/object:Gem::Requirement
99
+ prerelease: false
100
+ requirement: &id005 !ruby/object:Gem::Requirement
70
101
  requirements:
71
102
  - - ">="
72
103
  - !ruby/object:Gem::Version
104
+ segments:
105
+ - 1
106
+ - 0
107
+ - 0
73
108
  version: 1.0.0
74
- version:
109
+ type: :development
110
+ version_requirements: *id005
75
111
  - !ruby/object:Gem::Dependency
76
112
  name: minitest
77
- type: :development
78
- version_requirement:
79
- version_requirements: !ruby/object:Gem::Requirement
113
+ prerelease: false
114
+ requirement: &id006 !ruby/object:Gem::Requirement
80
115
  requirements:
81
116
  - - ">="
82
117
  - !ruby/object:Gem::Version
118
+ segments:
119
+ - 1
120
+ - 5
121
+ - 0
83
122
  version: 1.5.0
84
- version:
123
+ type: :development
124
+ version_requirements: *id006
85
125
  - !ruby/object:Gem::Dependency
86
126
  name: hoe
87
- type: :development
88
- version_requirement:
89
- version_requirements: !ruby/object:Gem::Requirement
127
+ prerelease: false
128
+ requirement: &id007 !ruby/object:Gem::Requirement
90
129
  requirements:
91
130
  - - ">="
92
131
  - !ruby/object:Gem::Version
93
- version: 2.5.0
94
- version:
132
+ segments:
133
+ - 2
134
+ - 6
135
+ - 0
136
+ version: 2.6.0
137
+ type: :development
138
+ version_requirements: *id007
95
139
  description: |-
96
140
  g1nn13 fork changes:
97
141
 
98
142
  * added buffer() method to get image buffer for writing (to Amazon S3)
99
143
  * added fit_within() method to resize an image to fit within a specified
100
144
  height and width without changing the image's aspect ratio
145
+ * added resize_with_crop() to resize and crop images where the
146
+ target aspect ratio differs from the original aspect ratio. This is
147
+ for converting portrait to landscape and landscape to portrait.
148
+
149
+
101
150
 
102
151
  ImageScience is a clean and happy Ruby library that generates
103
152
  thumbnails -- and kicks the living crap out of RMagick. Oh, and it
@@ -138,20 +187,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
187
  requirements:
139
188
  - - ">="
140
189
  - !ruby/object:Gem::Version
190
+ segments:
191
+ - 0
141
192
  version: "0"
142
- version:
143
193
  required_rubygems_version: !ruby/object:Gem::Requirement
144
194
  requirements:
145
195
  - - ">="
146
196
  - !ruby/object:Gem::Version
197
+ segments:
198
+ - 0
147
199
  version: "0"
148
- version:
149
200
  requirements: []
150
201
 
151
202
  rubyforge_project: g1nn13-image_science
152
- rubygems_version: 1.3.5
203
+ rubygems_version: 1.3.6
153
204
  signing_key:
154
205
  specification_version: 3
155
- summary: "g1nn13 fork changes: * added buffer() method to get image buffer for writing (to Amazon S3) * added fit_within() method to resize an image to fit within a specified height and width without changing the image's aspect ratio ImageScience is a clean and happy Ruby library that generates thumbnails -- and kicks the living crap out of RMagick"
206
+ summary: "g1nn13 fork changes: * added buffer() method to get image buffer for writing (to Amazon S3) * added fit_within() method to resize an image to fit within a specified height and width without changing the image's aspect ratio * added resize_with_crop() to resize and crop images where the target aspect ratio differs from the original aspect ratio"
156
207
  test_files:
157
208
  - test/test_image_science.rb
metadata.gz.sig ADDED
@@ -0,0 +1,5 @@
1
+ Pl\3N��>KA���C��y{�[ZT��}��ͻC�ه?��M��ƅs�#�):��
2
+ C����B�du�9��
3
+ xܩ�DH�@e��P8���X��e<mm��-�m��N�b��4�Î`b�]����
4
+ �WZ�rO�.!�~2nB
5
+ �!;w(t}�e�0Fh#[��t�͎7(�ő�?�*!�ӛ^�Q��j��s���Q��8�O���; �+gg��v��%�u �t}����Ǧ]�� E�ʞ]�&����_