devil 0.1.8 → 0.1.8.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,4 +1,19 @@
1
- 2009-10-21
1
+ 2009-10-25 John Mair (Banisterfiend)
2
+ version 0.1.8.5
3
+ * added hooks: prepare_image_hook, create_image_hook, load_image_hook
4
+ * e.g Devil.set_options :load_image_hook => proc { IL::ConvertImage(IL::RGBA, IL::UNSIGNED_BYTE) }
5
+ * added Devil.create_image() method for creating blank images (useful as a blitting canvas?)
6
+ * added :color parameter to create_image (to set background color of new image)
7
+ * added :in_profile and :out_profile to Devil.load_image and Devil.create_image
8
+ * color profiles do not appear to work! so not officially supported or documented.
9
+ * fixed gosu image flip bug
10
+ * added more tests and rdoc
11
+
12
+ 2009-10-22 John Mair (Banisterfiend)
13
+ * added ESC exit from Devil::Image#show
14
+ * added optional :filter parameter to Devil::Image#thumbnail and Devil::Image#resize
15
+
16
+ 2009-10-21 John Mair (Banisterfiend)
2
17
  version 0.1.8
3
18
  * made LANCZOS3 scaling filter the default for highquality thumbnails
4
19
  * changed clear color to DevIL default (mother of pearl and full alpha)
data/README CHANGED
@@ -1,4 +1,4 @@
1
- Ruby Devil version 0.1.8
1
+ Ruby Devil version 0.1.8.5
2
2
  ========================
3
3
 
4
4
  * Original author: Jaroslaw Tworek <dev.jrx@gmail.com>
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ require 'rake/gempackagetask'
8
8
  require 'rake/testtask'
9
9
  require 'rake/rdoctask'
10
10
 
11
- DEVIL_VERSION = "0.1.8"
11
+ DEVIL_VERSION = "0.1.8.5"
12
12
 
13
13
  dlext = Config::CONFIG['DLEXT']
14
14
 
@@ -119,7 +119,12 @@ static VALUE il_TexImage(VALUE obj, VALUE rb_width, VALUE rb_height,
119
119
  ILenum type = NUM2INT(rb_type);
120
120
 
121
121
  /* from ILvoid */
122
- void* data = ImageData2Arr(rb_data);
122
+ void * data = NULL;
123
+
124
+ if(NIL_P(rb_data))
125
+ data = NULL;
126
+ else
127
+ data = ImageData2Arr(rb_data);
123
128
 
124
129
  ILboolean flag = ilTexImage(width, height, depth,
125
130
  bpp, format, type, data);
@@ -249,6 +254,22 @@ static VALUE il_Disable(VALUE obj, VALUE rb_mode) {
249
254
  return flag ? Qtrue : Qfalse;
250
255
  }
251
256
 
257
+ static VALUE il_ApplyProfile(VALUE obj, VALUE rb_inprofile, VALUE rb_outprofile)
258
+ {
259
+ char * inprofile = NULL;
260
+ char * outprofile = StringValuePtr(rb_outprofile);
261
+ ILboolean flag;
262
+
263
+ if(NIL_P(rb_inprofile))
264
+ inprofile = NULL;
265
+ else
266
+ inprofile = StringValuePtr(rb_inprofile);
267
+
268
+ flag = ilApplyProfile(inprofile, outprofile);
269
+
270
+ return flag ? Qtrue : Qfalse;
271
+ }
272
+
252
273
  static VALUE il_GetInteger(VALUE obj, VALUE rb_mode) {
253
274
  ILenum mode = NUM2INT(rb_mode);
254
275
 
@@ -266,7 +287,7 @@ static VALUE il_ConvertImage(VALUE obj, VALUE rb_destformat, VALUE rb_desttype)
266
287
  }
267
288
 
268
289
  /* TODO: MAKE SURE NO MEMORY LEAKS! */
269
- /* this function is not actualy in the DevIL API, but im adding it here for convenience */
290
+ /* this function is not actually in the DevIL API, but im adding it here for convenience */
270
291
  static VALUE bf_ToBlob(VALUE obj)
271
292
  {
272
293
  ILuint width, height, saved_image, copy_image;
@@ -399,6 +420,7 @@ InitializeIL() {
399
420
  rb_define_module_function(mIL, "OriginFunc", il_OriginFunc, 1);
400
421
  rb_define_module_function(mIL, "ClearColour", il_ClearColour, 4);
401
422
  rb_define_module_function(mIL, "ClearImage", il_ClearImage, 0);
423
+ rb_define_module_function(mIL, "ApplyProfile", il_ApplyProfile, 2);
402
424
  /* end of methods added by banisterfiend */
403
425
 
404
426
  //////////////////////////////////
@@ -19,17 +19,26 @@ module Devil
19
19
  include IL
20
20
  include ILU
21
21
 
22
- VERSION = '0.1.8'
22
+ VERSION = '0.1.8.5'
23
23
 
24
24
  class << self
25
25
 
26
26
  # loads +file+ and returns a new image
27
27
  # Optionally accepts a block and yields the newly created image to the block.
28
- def load_image(file, &block)
29
- name = IL.GenImages(1).first
30
- IL.BindImage(name)
28
+ def load_image(file, options={}, &block)
29
+ name = prepare_image
30
+ out_profile = options[:out_profile]
31
+ in_profile = options[:in_profile]
32
+
31
33
  IL.LoadImage(file)
32
34
 
35
+ # apply a color profile if one is provided
36
+ IL.ApplyProfile(in_profile, out_profile) if out_profile
37
+
38
+ # run the proc (if it exists)
39
+ load_image_proc = Devil.get_options[:load_image_hook]
40
+ load_image_proc.call if load_image_proc
41
+
33
42
  if (error_code = IL.GetError) != IL::NO_ERROR
34
43
  raise RuntimeError, "an error occured while trying to "+
35
44
  "load the image #{file}. #{ILU.ErrorString(error_code)}"
@@ -45,6 +54,47 @@ module Devil
45
54
 
46
55
  alias_method :with_image, :load_image
47
56
  alias_method :load, :load_image
57
+
58
+ # returns a blank image of +width+ and +height+.
59
+ # Optionally accepts the :color hash param that fills the new image with a color
60
+ # (see: Devil.set_options :clear_color)
61
+ # Optionally accepts a block and yields the newly created image to the block.
62
+ def create_image(width, height, options={}, &block)
63
+ name = prepare_image
64
+ out_profile = options[:out_profile]
65
+ in_profile = options[:in_profile]
66
+
67
+ clear_color = options[:color]
68
+
69
+ IL.TexImage(width, height, 1, 4, IL::RGBA, IL::UNSIGNED_BYTE, nil)
70
+
71
+ # apply a color profile if one is provided
72
+ IL.ApplyProfile(in_profile, out_profile) if out_profile
73
+
74
+ IL.ClearColour(*clear_color) if clear_color
75
+ IL.ClearImage
76
+ IL.ClearColour(*Devil.get_options[:clear_color]) if clear_color
77
+
78
+ # run the proc (if it exists)
79
+ create_image_proc = Devil.get_options[:create_image_hook]
80
+ create_image_proc.call if create_image_proc
81
+
82
+ if (error_code = IL.GetError) != IL::NO_ERROR
83
+ raise RuntimeError, "an error occured while trying to "+
84
+ "create an image. #{ILU.ErrorString(error_code)}"
85
+ end
86
+
87
+ img = Image.new(name, nil)
88
+ if block
89
+ block.call(img)
90
+ end
91
+
92
+ img
93
+ end
94
+
95
+ alias_method :create_blank_image, :create_image
96
+ alias_method :create_blank, :create_image
97
+ alias_method :blank_image, :create_image
48
98
 
49
99
  # convert an image +blob+ with +width+ and +height+
50
100
  # to a bona fide image
@@ -63,7 +113,7 @@ module Devil
63
113
  #
64
114
  # :placement determines where in the canvas the image will be placed after
65
115
  # the canvas has been enlarged using the 'enlarge_canvas' method.
66
- # Valid parameters are: Devil::Center, Devil::LOWER_LEFT, Devil::UPPER_RIGHT, etc
116
+ # Valid parameters are: Devil::CENTER, Devil::LOWER_LEFT, Devil::UPPER_RIGHT, etc
67
117
  #
68
118
  # :clear_color sets the current clearing colour to be used by future
69
119
  # calls to clear. rotate and enlarge_canvas both use these values to
@@ -83,7 +133,7 @@ module Devil
83
133
  def set_options(options={})
84
134
  @options.merge!(options)
85
135
 
86
- # update the scale_filter
136
+ # update the config. options
87
137
  ILU.ImageParameter(ILU::FILTER, @options[:scale_filter])
88
138
  ILU.ImageParameter(ILU::PLACEMENT, @options[:placement])
89
139
  IL.ClearColour(*@options[:clear_color])
@@ -101,18 +151,20 @@ module Devil
101
151
  IL.Init
102
152
  ILU.Init
103
153
 
104
- set_option_defaults
154
+ set_defaults
105
155
  end
106
156
 
107
- private
108
-
109
- def set_option_defaults
157
+ # restore Devil's default configuration.
158
+ def set_defaults
110
159
  @options = {
111
160
  :scale_filter => ILU::SCALE_LANCZOS3,
112
161
  :edge_filter => :prewitt,
113
162
  :window_size => [1024, 768],
114
163
  :clear_color => [255, 248, 230, 0],
115
164
  :placement => ILU::CENTER,
165
+ :prepare_image_hook => nil,
166
+ :load_image_hook => nil,
167
+ :create_image_hook => nil,
116
168
  }
117
169
 
118
170
  # configurable options
@@ -122,250 +174,286 @@ module Devil
122
174
 
123
175
  # fixed options
124
176
  IL.Enable(IL::FILE_OVERWRITE)
177
+ IL.Enable(IL::ORIGIN_SET)
178
+ IL.OriginFunc(IL::ORIGIN_LOWER_LEFT)
125
179
  end
126
- end
127
-
128
- class Image
129
- attr_reader :name, :file
130
180
 
131
- def initialize(name, file)
132
- @name = name
133
- @file = file
181
+ alias_method :restore_defaults, :set_defaults
134
182
 
135
- ObjectSpace.define_finalizer( self, proc { IL.DeleteImages(1, [name]) } )
136
- end
137
-
138
- # returns the width of the image.
139
- def width
140
- action { IL.GetInteger(IL::IMAGE_WIDTH) }
141
- end
183
+ private
142
184
 
143
- alias_method :columns, :width
185
+ def prepare_image
186
+ name = IL.GenImages(1).first
187
+ IL.BindImage(name)
188
+
189
+ # run the proc (if it exists)
190
+ prepare_image_proc = Devil.get_options[:prepare_image_hook]
191
+ prepare_image_proc.call if prepare_image_proc
144
192
 
145
- # returns the height of the image.
146
- def height
147
- action { IL.GetInteger(IL::IMAGE_HEIGHT) }
193
+ name
148
194
  end
195
+ end
196
+ end
197
+ # end of Devil module
149
198
 
150
- alias_method :rows, :height
199
+ # wraps a DevIL image
200
+ class Devil::Image
201
+ attr_reader :name, :file
151
202
 
152
- # saves the image to +file+. If no +file+ is provided default to the opened file.
153
- def save(file = @file)
154
- raise "This image does not have an associated file. Please provide an explicit file name when saving." if !file
155
-
156
- action { IL.SaveImage(file) }
157
- self
158
- end
159
-
160
- # resize the image to +width+ and +height+. Aspect ratios of the image do not have to be the same.
161
- def resize(width, height)
162
- action { ILU.Scale(width, height, 1) }
163
- self
164
- end
203
+ def initialize(name, file)
204
+ @name = name
205
+ @file = file
165
206
 
166
- # Creates a proportional thumbnail of the image scaled so its longest.
167
- # edge is resized to +size+.
168
- def thumbnail(size)
207
+ ObjectSpace.define_finalizer( self, proc { IL.DeleteImages(1, [name]) } )
208
+ end
209
+
210
+ # returns the width of the image.
211
+ def width
212
+ action { IL.GetInteger(IL::IMAGE_WIDTH) }
213
+ end
169
214
 
170
- # this thumbnail code from image_science.rb
171
- w, h = width, height
172
- scale = size.to_f / (w > h ? w : h)
173
- resize((w * scale).to_i, (h * scale).to_i)
174
- self
175
- end
215
+ alias_method :columns, :width
176
216
 
177
- # return a deep copy of the current image.
178
- def dup
179
- new_image_name = action { IL.CloneCurImage }
180
- Image.new(new_image_name, nil)
181
- end
217
+ # returns the height of the image.
218
+ def height
219
+ action { IL.GetInteger(IL::IMAGE_HEIGHT) }
220
+ end
182
221
 
183
- alias_method :clone, :dup
222
+ alias_method :rows, :height
184
223
 
185
- # crop the current image.
186
- # +xoff+ number of pixels to skip in x direction.
187
- # +yoff+ number of pixels to skip in y direction.
188
- # +width+ number of pixels to preserve in x direction.
189
- # +height+ number of pixels to preserve in y direction.
190
- def crop(xoff, yoff, width, height)
191
- action { ILU.Crop(xoff, yoff, 1, width, height, 1) }
192
- self
193
- end
224
+ # saves the image to +file+. If no +file+ is provided default to the opened file.
225
+ def save(file = @file)
226
+ raise "This image does not have an associated file. Please provide an explicit file name when saving." if !file
227
+
228
+ action { IL.SaveImage(file) }
229
+ self
230
+ end
231
+
232
+ # resize the image to +width+ and +height+. Aspect ratios of the image do not have to be the same.
233
+ # Optional :filter hash parameter that maps to a valid scale filter
234
+ # (see: Devil.set_options :scale_filter)
235
+ def resize(width, height, options = {})
236
+ filter = options[:filter]
194
237
 
195
- # enlarge the canvas of current image to +width+ and +height+.
196
- def enlarge_canvas(width, height)
197
- if width < self.width || height < self.height
198
- raise "width and height parameters must be larger than current image width and height"
199
- end
200
-
201
- action { ILU.EnlargeCanvas(width, height, 1) }
202
- self
238
+ action do
239
+ ILU.ImageParameter(ILU::FILTER, filter) if filter
240
+ ILU.Scale(width, height, 1)
241
+ ILU.ImageParameter(ILU::FILTER, Devil.get_options[:scale_filter]) if filter
203
242
  end
243
+
244
+ self
245
+ end
204
246
 
205
- # splice the +source+ image into current image at position +x+ and +y+.
206
- # Takes an optional +:crop+ hash parameter that has the following format: +:crop => [sx, sy, width, height]+
207
- # +sx+, +sy+, +width, +height+ crop the source image to be spliced.
208
- # +sx+ is how many pixels to skip in x direction of source image.
209
- # +sy+ is how many pixels to skip in y direction of source image.
210
- # +width+ number of pixels to preserve in x direction of source image.
211
- # +height+ number of pixels to preserve in y direction of source image.
212
- # if no +:crop+ parameter is provided then the whole image is spliced in.
213
- def blit(source, x, y, options = {})
214
- options = {
215
- :crop => [0, 0, source.width, source.height]
216
- }.merge!(options)
217
-
218
- action do
219
- IL.Blit(source.name, x, y, 0, options[:crop][0], options[:crop][1], 0,
220
- options[:crop][2], options[:crop][3], 1)
221
- end
222
-
223
- self
224
- end
247
+ # Creates a proportional thumbnail of the image scaled so its longest
248
+ # edge is resized to +size+.
249
+ # Optional :filter hash parameter that maps to a valid scale filter
250
+ # (see: Devil.set_options :scale_filter)
251
+ def thumbnail(size, options = {})
252
+
253
+ # this thumbnail code from image_science.rb
254
+ w, h = width, height
255
+ scale = size.to_f / (w > h ? w : h)
256
+ resize((w * scale).to_i, (h * scale).to_i, options)
257
+ self
258
+ end
225
259
 
226
- alias_method :composite, :blit
260
+ # return a deep copy of the current image.
261
+ def dup
262
+ new_image_name = action { IL.CloneCurImage }
263
+ Devil::Image.new(new_image_name, nil)
264
+ end
227
265
 
228
- # reflect image about its y axis.
229
- def mirror
230
- action { ILU.Mirror }
231
- self
232
- end
266
+ alias_method :clone, :dup
233
267
 
234
- # use prewitt or sobel filters to detect the edges in the current image.
235
- def edge_detect
236
- case Devil.get_options[:edge_filter]
237
- when :prewitt
238
- action { ILU.EdgeDetectP }
239
- when :sobel
240
- action { ILU.EdgeDetectS }
241
- else
242
- raise "No such edge filter #{Devil.get_options[:edge_filter]}. Use :prewitt or :sobel"
243
- end
244
- self
245
- end
268
+ # crop the current image.
269
+ # +xoff+ number of pixels to skip in x direction.
270
+ # +yoff+ number of pixels to skip in y direction.
271
+ # +width+ number of pixels to preserve in x direction.
272
+ # +height+ number of pixels to preserve in y direction.
273
+ def crop(xoff, yoff, width, height)
274
+ action { ILU.Crop(xoff, yoff, 1, width, height, 1) }
275
+ self
276
+ end
246
277
 
247
- # embosses an image, causing it to have a "relief" feel to it using a convolution filter.
248
- def emboss
249
- action { ILU.Emboss }
250
- self
278
+ # enlarge the canvas of current image to +width+ and +height+.
279
+ def enlarge_canvas(width, height)
280
+ if width < self.width || height < self.height
281
+ raise "width and height parameters must be larger than current image width and height"
251
282
  end
283
+
284
+ action { ILU.EnlargeCanvas(width, height, 1) }
285
+ self
286
+ end
252
287
 
253
- # applies a strange color distortion effect to the image giving a preternatural feel
254
- def alienify
255
- action { ILU.Alienify }
256
- self
288
+ # splice the +source+ image into current image at position +x+ and +y+.
289
+ # Takes an optional +:crop+ hash parameter that has the following format: +:crop => [sx, sy, width, height]+
290
+ # +sx+, +sy+, +width, +height+ crop the source image to be spliced.
291
+ # +sx+ is how many pixels to skip in x direction of source image.
292
+ # +sy+ is how many pixels to skip in y direction of source image.
293
+ # +width+ number of pixels to preserve in x direction of source image.
294
+ # +height+ number of pixels to preserve in y direction of source image.
295
+ # if no +:crop+ parameter is provided then the whole image is spliced in.
296
+ def blit(source, x, y, options = {})
297
+ options = {
298
+ :crop => [0, 0, source.width, source.height]
299
+ }.merge!(options)
300
+
301
+ action do
302
+ IL.Blit(source.name, x, y, 0, options[:crop][0], options[:crop][1], 0,
303
+ options[:crop][2], options[:crop][3], 1)
257
304
  end
305
+
306
+ self
307
+ end
258
308
 
259
- # performs a gaussian blur on the image. The blur is performed +iter+ times.
260
- def blur(iter)
261
- action { ILU.BlurGaussian(iter) }
262
- self
263
- end
309
+ alias_method :composite, :blit
264
310
 
265
- # 'pixelize' the image using a pixel size of +pixel_size+.
266
- def pixelize(pixel_size)
267
- action { ILU.Pixelize(pixel_size) }
268
- self
269
- end
311
+ # reflect image about its y axis.
312
+ def mirror
313
+ action { ILU.Mirror }
314
+ self
315
+ end
270
316
 
271
- # add random noise to the image. +factor+ is the tolerance to use.
272
- # accepeted values range from 0.0 - 1.0.
273
- def noisify(factor)
274
- action { ILU.Noisify(factor) }
275
- self
276
- end
317
+ # use prewitt or sobel filters to detect the edges in the current image.
318
+ # Optional :filter hash parameter selects filter to use (:prewitt or :sobel).
319
+ # (see: Devil.set_options :edge_filter)
320
+ def edge_detect(options={})
321
+ options = {
322
+ :filter => Devil.get_options[:edge_filter]
323
+ }.merge!(options)
324
+
325
+ case options[:filter]
326
+ when :prewitt
327
+ action { ILU.EdgeDetectP }
328
+ when :sobel
329
+ action { ILU.EdgeDetectS }
330
+ else
331
+ raise "No such edge filter #{options[:filter]}. Use :prewitt or :sobel"
332
+ end
333
+ self
334
+ end
277
335
 
278
- # The sharpening +factor+ must be in the range of 0.0 - 2.5. A value of 1.0 for the sharpening.
279
- # factor will have no effect on the image. Values in the range 1.0 - 2.5 will sharpen the
280
- # image, with 2.5 having the most pronounced sharpening effect. Values from 0.0 to 1.0 do
281
- # a type of reverse sharpening, blurring the image. Values outside of the 0.0 - 2.5 range
282
- # produce undefined results.
283
- #
284
- # The number of +iter+ (iterations) to perform will usually be 1, but to achieve more sharpening,
285
- # increase the number of iterations.
286
- def sharpen(factor, iter)
287
- action { ILU.Sharpen(factor, iter) }
288
- self
289
- end
336
+ # embosses an image, causing it to have a "relief" feel to it using a convolution filter.
337
+ def emboss
338
+ action { ILU.Emboss }
339
+ self
340
+ end
290
341
 
291
- # applies gamma correction to an image using an exponential curve.
292
- # +factor+ is gamma correction factor to use.
293
- # A value of 1.0 leaves the image unmodified.
294
- # Values in the range 0.0 - 1.0 darken the image
295
- # Values above 1.0 brighten the image.
296
- def gamma_correct(factor)
297
- action { ILU.GammaCorrect(factor) }
298
- self
299
- end
342
+ # applies a strange color distortion effect to the image giving a preternatural feel
343
+ def alienify
344
+ action { ILU.Alienify }
345
+ self
346
+ end
300
347
 
301
- # invert the color of every pixel in the image.
302
- def negate
303
- action { ILU.Negative }
304
- self
305
- end
348
+ # performs a gaussian blur on the image. The blur is performed +iter+ times.
349
+ def blur(iter)
350
+ action { ILU.BlurGaussian(iter) }
351
+ self
352
+ end
306
353
 
307
- alias_method :negative, :negate
354
+ # 'pixelize' the image using a pixel size of +pixel_size+.
355
+ def pixelize(pixel_size)
356
+ action { ILU.Pixelize(pixel_size) }
357
+ self
358
+ end
308
359
 
309
- # +factor+ describes desired contrast to use
310
- # A value of 1.0 has no effect on the image.
311
- # Values between 1.0 and 1.7 increase the amount of contrast (values above 1.7 have no effect)
312
- # Valid range of +factor+ is 0.0 - 1.7.
313
- def contrast(factor)
314
- action { ILU.Contrast(factor) }
315
- self
316
- end
360
+ # add random noise to the image. +factor+ is the tolerance to use.
361
+ # accepeted values range from 0.0 - 1.0.
362
+ def noisify(factor)
363
+ action { ILU.Noisify(factor) }
364
+ self
365
+ end
317
366
 
318
- # darkens the bright colours and lightens the dark
319
- # colours, reducing the contrast in an image or 'equalizing' it.
320
- def equalize
321
- action { ILU.Equalize }
322
- self
323
- end
367
+ # The sharpening +factor+ must be in the range of 0.0 - 2.5. A value of 1.0 for the sharpening.
368
+ # factor will have no effect on the image. Values in the range 1.0 - 2.5 will sharpen the
369
+ # image, with 2.5 having the most pronounced sharpening effect. Values from 0.0 to 1.0 do
370
+ # a type of reverse sharpening, blurring the image. Values outside of the 0.0 - 2.5 range
371
+ # produce undefined results.
372
+ #
373
+ # The number of +iter+ (iterations) to perform will usually be 1, but to achieve more sharpening,
374
+ # increase the number of iterations.
375
+ def sharpen(factor, iter)
376
+ action { ILU.Sharpen(factor, iter) }
377
+ self
378
+ end
324
379
 
325
- # returns the image data in the form of a ruby string.
326
- # The image data is formatted to RGBA / UNSIGNED BYTE.
327
- def to_blob
328
- action { IL.ToBlob }
329
- end
380
+ # applies gamma correction to an image using an exponential curve.
381
+ # +factor+ is gamma correction factor to use.
382
+ # A value of 1.0 leaves the image unmodified.
383
+ # Values in the range 0.0 - 1.0 darken the image
384
+ # Values above 1.0 brighten the image.
385
+ def gamma_correct(factor)
386
+ action { ILU.GammaCorrect(factor) }
387
+ self
388
+ end
330
389
 
331
- # flip the image about its x axis.
332
- def flip
333
- action { ILU.FlipImage }
334
- self
335
- end
390
+ # invert the color of every pixel in the image.
391
+ def negate
392
+ action { ILU.Negative }
393
+ self
394
+ end
336
395
 
337
- # rotate an image about its central point by +angle+ degrees (counter clockwise).
338
- def rotate(angle)
339
- action { ILU.Rotate(angle) }
340
- self
341
- end
396
+ alias_method :negative, :negate
342
397
 
343
- # simply clears the image to the 'clear color' (specified using Devil.set_options(:clear_color => [r, g, b, a])
344
- def clear
345
- action { IL.ClearImage }
346
- self
347
- end
398
+ # +factor+ describes desired contrast to use
399
+ # A value of 1.0 has no effect on the image.
400
+ # Values between 1.0 and 1.7 increase the amount of contrast (values above 1.7 have no effect)
401
+ # Valid range of +factor+ is 0.0 - 1.7.
402
+ def contrast(factor)
403
+ action { ILU.Contrast(factor) }
404
+ self
405
+ end
348
406
 
349
- private
407
+ # darkens the bright colours and lightens the dark
408
+ # colours, reducing the contrast in an image or 'equalizing' it.
409
+ def equalize
410
+ action { ILU.Equalize }
411
+ self
412
+ end
350
413
 
351
- def set_binding
352
- IL.BindImage(@name)
353
- end
414
+ # returns the image data in the form of a ruby string.
415
+ # The image data is formatted to RGBA / UNSIGNED BYTE.
416
+ def to_blob
417
+ action { IL.ToBlob }
418
+ end
354
419
 
355
- def error_check
356
- if (error_code = IL.GetError) != IL::NO_ERROR
357
- raise RuntimeError, "An error occured. #{ILU.ErrorString(error_code)}"
358
- end
359
- end
420
+ # flip the image about its x axis.
421
+ def flip
422
+ action { ILU.FlipImage }
423
+ self
424
+ end
360
425
 
361
- def action
362
- set_binding
363
- result = yield
364
- error_check
365
-
366
- result
426
+ # rotate an image about its central point by +angle+ degrees (counter clockwise).
427
+ def rotate(angle)
428
+ action { ILU.Rotate(angle) }
429
+ self
430
+ end
431
+
432
+ # simply clears the image to the 'clear color' (specified using Devil.set_options(:clear_color => [r, g, b, a])
433
+ def clear
434
+ action { IL.ClearImage }
435
+ self
436
+ end
437
+
438
+ private
439
+
440
+ def set_binding
441
+ IL.BindImage(@name)
442
+ end
443
+
444
+ def error_check
445
+ if (error_code = IL.GetError) != IL::NO_ERROR
446
+ raise RuntimeError, "An error occured. #{ILU.ErrorString(error_code)}"
367
447
  end
368
448
  end
449
+
450
+ def action
451
+ set_binding
452
+ result = yield
453
+ error_check
454
+
455
+ result
456
+ end
369
457
  end
370
458
 
371
459
  Devil.init
@@ -1,3 +1,5 @@
1
+ # (C) John Mair 2009, under the MIT licence
2
+
1
3
  require 'texplay'
2
4
  require 'devil'
3
5
 
@@ -19,7 +21,7 @@ module TexPlay
19
21
  devil_img = nil
20
22
  capture {
21
23
  devil_img = Devil.from_blob(self.to_blob, self.width, self.height)
22
- devil_img.flip
24
+ devil_img
23
25
  }
24
26
  devil_img
25
27
  end
@@ -40,10 +42,8 @@ class Gosu::Window
40
42
  glEnable(GL_TEXTURE_2D)
41
43
  glBindTexture(GL_TEXTURE_2D, canvas_texture_id)
42
44
 
43
- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1)
44
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
45
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
46
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, self.width, self.height, 0, GL_RGB, GL_UNSIGNED_BYTE, "\0" * self.width * self.height * 3)
45
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, self.width, self.height, 0,
46
+ GL_RGB, GL_UNSIGNED_BYTE, "\0" * self.width * self.height * 3)
47
47
 
48
48
  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, self.width, self.height, 0)
49
49
 
@@ -65,7 +65,7 @@ class Gosu::Image
65
65
  if file.respond_to?(:to_blob) || file =~ /\.(bmp|png)$/
66
66
  original_new_redux(window, file, *args, &block)
67
67
  else
68
- original_new_redux(window, Devil.load(file), *args, &block)
68
+ original_new_redux(window, Devil.load(file).flip, *args, &block)
69
69
  end
70
70
  end
71
71
  end
@@ -98,6 +98,8 @@ class Devil::Image
98
98
 
99
99
  def draw # :nodoc:
100
100
  @show_list.each { |v| v[:image].draw_rot(v[:x], v[:y], 1, 0) }
101
+
102
+ exit if button_down?(Gosu::KbEscape)
101
103
  end
102
104
  end
103
105
 
@@ -111,7 +113,7 @@ class Devil::Image
111
113
  end
112
114
 
113
115
  # note we dup the image so the displayed image is a snapshot taken at the time #show is invoked
114
- @@window.show_list.push :image => Gosu::Image.new(@@window, self.dup), :x => x, :y => y
116
+ @@window.show_list.push :image => Gosu::Image.new(@@window, self.dup.flip), :x => x, :y => y
115
117
 
116
118
  self
117
119
  end
@@ -0,0 +1,17 @@
1
+ $direc = File.dirname(__FILE__)
2
+
3
+ $LOAD_PATH.push("#{$direc}/../lib/")
4
+
5
+ require 'rubygems'
6
+ require 'devil/gosu'
7
+
8
+ Devil.set_options :load_image_hook => proc { IL.ConvertImage(IL::RGBA, IL::UNSIGNED_BYTE) }
9
+
10
+ Devil.create_image(500, 500, :color => [255, 255, 0, 255]) do |img|
11
+ source1 = Devil.load("texture.png").thumbnail(100)
12
+ img.blit source1, 100, 100
13
+ img.blit source1, 400, 100
14
+ img.blit source1.dup.rotate(45), 100, 300
15
+ img.show
16
+ end
17
+
@@ -5,12 +5,12 @@ $LOAD_PATH.push("#{direc}/../lib/")
5
5
  require 'rubygems'
6
6
  require "devil/gosu"
7
7
 
8
- img = Devil.load_image("#{direc}/texture.jpg")
8
+ img = Devil.load_image("#{direc}/texture.png")
9
9
 
10
10
  img.crop(100,100, 200, 200)
11
11
  img_dup = img.dup
12
12
 
13
- img.negative
13
+ img.rotate(rand(360))
14
14
 
15
15
  img.show(200,200)
16
16
  img_dup.show(450, 200)
@@ -10,6 +10,7 @@ class W < Gosu::Window
10
10
  super(1024, 768, false, 20)
11
11
 
12
12
  @img = Gosu::Image.new(self, "#{$direc}/texture.jpg")
13
+ @img = @img.to_devil.save("cunt.png").to_gosu(self).to_devil.blur(5).to_gosu(self)
13
14
  end
14
15
 
15
16
  def draw
@@ -0,0 +1,27 @@
1
+ $direc = File.dirname(__FILE__)
2
+
3
+ $LOAD_PATH.push("#{$direc}/../lib/")
4
+
5
+ require 'rubygems'
6
+ require 'devil/gosu'
7
+
8
+ class W < Gosu::Window
9
+ def initialize
10
+ super(1024, 768, false, 20)
11
+
12
+ @img = Gosu::Image.new(self, "#{$direc}/texture.jpg")
13
+ @img = @img.to_devil.
14
+ emboss.
15
+ rotate(45).
16
+ to_gosu(self)
17
+ end
18
+
19
+ def draw
20
+ @img.draw 100, 50,1
21
+ end
22
+
23
+ end
24
+
25
+ w = W.new
26
+ w.show
27
+
@@ -0,0 +1,8 @@
1
+ $direc = File.dirname(__FILE__)
2
+
3
+ $LOAD_PATH.push("#{$direc}/../lib/")
4
+
5
+ require 'rubygems'
6
+ require 'devil/gosu'
7
+
8
+ Devil.load("texture.png", :inprofile => "sRGB.icm", :out_profile => "color/AdobeRGB1998.icc").save("texture_out.png")
@@ -6,6 +6,7 @@ require 'rubygems'
6
6
  require 'devil/gosu'
7
7
 
8
8
  Devil.load("texture.png") do |img|
9
- img.thumbnail(150).show
9
+ img.dup.thumbnail(150, :filter => Devil::NEAREST).show(100, 300)
10
+ img.dup.thumbnail(150).show(100, 100)
10
11
  end
11
12
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaroslaw Tworek, John Mair (banisterfiend)
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-20 00:00:00 -04:00
12
+ date: 2009-10-25 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -37,9 +37,12 @@ files:
37
37
  - test/test_gosu_load.rb
38
38
  - test/test_scale_algos.rb
39
39
  - test/test_new_api.rb
40
+ - test/test_blank.rb
40
41
  - test/test_clone_and_crop.rb
41
42
  - test/test_gosu_show.rb
43
+ - test/test_profile.rb
42
44
  - test/test_screenshot.rb
45
+ - test/test_gosu_roundtrip.rb
43
46
  - test/test_gosu_save.rb
44
47
  - test/test_thumbnail.rb
45
48
  - test/tank.png