devil 0.1.8-x86-mswin32-60 → 0.1.8.5-x86-mswin32-60
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/CHANGELOG +16 -1
- data/README +1 -1
- data/Rakefile +1 -1
- data/ext/devil/ruby_il.c +27 -4
- data/lib/1.8/devil.so +0 -0
- data/lib/1.9/devil.so +0 -0
- data/lib/devil.rb +299 -211
- data/lib/devil/gosu.rb +9 -7
- data/test/test_blank.rb +17 -0
- data/test/test_clone_and_crop.rb +2 -2
- data/test/test_gosu_load.rb +1 -0
- data/test/test_gosu_roundtrip.rb +27 -0
- data/test/test_profile.rb +8 -0
- data/test/test_thumbnail.rb +2 -1
- metadata +5 -2
data/CHANGELOG
CHANGED
@@ -1,4 +1,19 @@
|
|
1
|
-
2009-10-
|
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
data/Rakefile
CHANGED
data/ext/devil/ruby_il.c
CHANGED
@@ -116,12 +116,18 @@ static VALUE il_TexImage(VALUE obj, VALUE rb_width, VALUE rb_height,
|
|
116
116
|
ILuint depth = NUM2INT(rb_depth);
|
117
117
|
ILubyte bpp = NUM2INT(rb_bpp);
|
118
118
|
ILenum format = NUM2INT(rb_format);
|
119
|
-
ILenum type = NUM2INT(rb_type);
|
119
|
+
ILenum type = NUM2INT(rb_type);
|
120
|
+
ILboolean flag;
|
120
121
|
|
121
122
|
/* from ILvoid */
|
122
|
-
void* data =
|
123
|
+
void * data = NULL;
|
124
|
+
|
125
|
+
if(NIL_P(rb_data))
|
126
|
+
data = NULL;
|
127
|
+
else
|
128
|
+
data = ImageData2Arr(rb_data);
|
123
129
|
|
124
|
-
|
130
|
+
flag = ilTexImage(width, height, depth,
|
125
131
|
bpp, format, type, data);
|
126
132
|
return flag ? Qtrue : Qfalse;
|
127
133
|
}
|
@@ -249,6 +255,22 @@ static VALUE il_Disable(VALUE obj, VALUE rb_mode) {
|
|
249
255
|
return flag ? Qtrue : Qfalse;
|
250
256
|
}
|
251
257
|
|
258
|
+
static VALUE il_ApplyProfile(VALUE obj, VALUE rb_inprofile, VALUE rb_outprofile)
|
259
|
+
{
|
260
|
+
char * inprofile = NULL;
|
261
|
+
char * outprofile = StringValuePtr(rb_outprofile);
|
262
|
+
ILboolean flag;
|
263
|
+
|
264
|
+
if(NIL_P(rb_inprofile))
|
265
|
+
inprofile = NULL;
|
266
|
+
else
|
267
|
+
inprofile = StringValuePtr(rb_inprofile);
|
268
|
+
|
269
|
+
flag = ilApplyProfile(inprofile, outprofile);
|
270
|
+
|
271
|
+
return flag ? Qtrue : Qfalse;
|
272
|
+
}
|
273
|
+
|
252
274
|
static VALUE il_GetInteger(VALUE obj, VALUE rb_mode) {
|
253
275
|
ILenum mode = NUM2INT(rb_mode);
|
254
276
|
|
@@ -266,7 +288,7 @@ static VALUE il_ConvertImage(VALUE obj, VALUE rb_destformat, VALUE rb_desttype)
|
|
266
288
|
}
|
267
289
|
|
268
290
|
/* TODO: MAKE SURE NO MEMORY LEAKS! */
|
269
|
-
/* this function is not
|
291
|
+
/* this function is not actually in the DevIL API, but im adding it here for convenience */
|
270
292
|
static VALUE bf_ToBlob(VALUE obj)
|
271
293
|
{
|
272
294
|
ILuint width, height, saved_image, copy_image;
|
@@ -399,6 +421,7 @@ InitializeIL() {
|
|
399
421
|
rb_define_module_function(mIL, "OriginFunc", il_OriginFunc, 1);
|
400
422
|
rb_define_module_function(mIL, "ClearColour", il_ClearColour, 4);
|
401
423
|
rb_define_module_function(mIL, "ClearImage", il_ClearImage, 0);
|
424
|
+
rb_define_module_function(mIL, "ApplyProfile", il_ApplyProfile, 2);
|
402
425
|
/* end of methods added by banisterfiend */
|
403
426
|
|
404
427
|
//////////////////////////////////
|
data/lib/1.8/devil.so
CHANGED
Binary file
|
data/lib/1.9/devil.so
CHANGED
Binary file
|
data/lib/devil.rb
CHANGED
@@ -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 =
|
30
|
-
|
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
|
@@ -83,7 +133,7 @@ module Devil
|
|
83
133
|
def set_options(options={})
|
84
134
|
@options.merge!(options)
|
85
135
|
|
86
|
-
# update the
|
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
|
-
|
154
|
+
set_defaults
|
105
155
|
end
|
106
156
|
|
107
|
-
|
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
|
-
|
132
|
-
@name = name
|
133
|
-
@file = file
|
181
|
+
alias_method :restore_defaults, :set_defaults
|
134
182
|
|
135
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
199
|
+
# wraps a DevIL image
|
200
|
+
class Devil::Image
|
201
|
+
attr_reader :name, :file
|
151
202
|
|
152
|
-
|
153
|
-
|
154
|
-
|
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
|
-
|
167
|
-
|
168
|
-
|
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
|
-
|
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
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
end
|
217
|
+
# returns the height of the image.
|
218
|
+
def height
|
219
|
+
action { IL.GetInteger(IL::IMAGE_HEIGHT) }
|
220
|
+
end
|
182
221
|
|
183
|
-
|
222
|
+
alias_method :rows, :height
|
184
223
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
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
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
#
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
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
|
-
|
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
|
-
|
229
|
-
def mirror
|
230
|
-
action { ILU.Mirror }
|
231
|
-
self
|
232
|
-
end
|
266
|
+
alias_method :clone, :dup
|
233
267
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
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
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
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
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
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
|
-
|
260
|
-
def blur(iter)
|
261
|
-
action { ILU.BlurGaussian(iter) }
|
262
|
-
self
|
263
|
-
end
|
309
|
+
alias_method :composite, :blit
|
264
310
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
311
|
+
# reflect image about its y axis.
|
312
|
+
def mirror
|
313
|
+
action { ILU.Mirror }
|
314
|
+
self
|
315
|
+
end
|
270
316
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
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
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
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
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
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
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
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
|
-
|
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
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
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
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
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
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
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
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
390
|
+
# invert the color of every pixel in the image.
|
391
|
+
def negate
|
392
|
+
action { ILU.Negative }
|
393
|
+
self
|
394
|
+
end
|
336
395
|
|
337
|
-
|
338
|
-
def rotate(angle)
|
339
|
-
action { ILU.Rotate(angle) }
|
340
|
-
self
|
341
|
-
end
|
396
|
+
alias_method :negative, :negate
|
342
397
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
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
|
-
|
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
|
-
|
352
|
-
|
353
|
-
|
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
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
420
|
+
# flip the image about its x axis.
|
421
|
+
def flip
|
422
|
+
action { ILU.FlipImage }
|
423
|
+
self
|
424
|
+
end
|
360
425
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
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
|
data/lib/devil/gosu.rb
CHANGED
@@ -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
|
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
|
-
|
44
|
-
|
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
|
data/test/test_blank.rb
ADDED
@@ -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
|
+
|
data/test/test_clone_and_crop.rb
CHANGED
@@ -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.
|
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.
|
13
|
+
img.rotate(rand(360))
|
14
14
|
|
15
15
|
img.show(200,200)
|
16
16
|
img_dup.show(450, 200)
|
data/test/test_gosu_load.rb
CHANGED
@@ -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
|
+
|
data/test/test_thumbnail.rb
CHANGED
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: x86-mswin32-60
|
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-
|
12
|
+
date: 2009-10-26 00:00:00 +13:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -33,12 +33,15 @@ files:
|
|
33
33
|
- ext/devil/ruby_devil_ext.c
|
34
34
|
- ext/devil/ruby_il.c
|
35
35
|
- ext/devil/ruby_ilu.c
|
36
|
+
- test/test_blank.rb
|
36
37
|
- test/test_blit.rb
|
37
38
|
- test/test_clone_and_crop.rb
|
38
39
|
- test/test_gosu_load.rb
|
40
|
+
- test/test_gosu_roundtrip.rb
|
39
41
|
- test/test_gosu_save.rb
|
40
42
|
- test/test_gosu_show.rb
|
41
43
|
- test/test_new_api.rb
|
44
|
+
- test/test_profile.rb
|
42
45
|
- test/test_scale_algos.rb
|
43
46
|
- test/test_screenshot.rb
|
44
47
|
- test/test_thumbnail.rb
|