graffik 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +20 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/ext/graffik/extconf.rb +14 -0
- data/ext/graffik/graffik.c +248 -0
- data/graffik.gemspec +43 -0
- metadata +72 -0
data/README.markdown
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Graffik
|
2
|
+
=======
|
3
|
+
|
4
|
+
Graffik is a fast, light-weight image manipulation library.
|
5
|
+
|
6
|
+
Example
|
7
|
+
-------
|
8
|
+
|
9
|
+
Graffic::Image('photo.jpg') do |img|
|
10
|
+
img.thumbnail(500) do |resized|
|
11
|
+
resized.write('thumbnail.jpg')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Requirements
|
16
|
+
------------
|
17
|
+
|
18
|
+
* [FreeImage][1]
|
19
|
+
|
20
|
+
[1]: http://freeimage.sourceforge.net/ "FreeImage"
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "graffik"
|
5
|
+
gemspec.summary = "Graffik is a fast, light-weight image manipulation library."
|
6
|
+
gemspec.description = "Graffik is a Ruby wrapper for the FreeImage library."
|
7
|
+
gemspec.email = "jeremy@jeremyboles.com"
|
8
|
+
gemspec.homepage = "http://github.com/jeremyboles/Graffik"
|
9
|
+
gemspec.authors = ["Jeremy Boles"]
|
10
|
+
gemspec.files.exclude '.DS_Store', '.gitignore'
|
11
|
+
end
|
12
|
+
rescue LoadError
|
13
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
14
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Loads mkmf which is used to make makefiles for Ruby extensions
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
# Add FreeImage
|
5
|
+
$LIBS << "-lfreeimage"
|
6
|
+
|
7
|
+
# Give it a name
|
8
|
+
extension_name = 'graffik'
|
9
|
+
|
10
|
+
# The destination
|
11
|
+
dir_config(extension_name)
|
12
|
+
|
13
|
+
# Do the work
|
14
|
+
create_makefile(extension_name)
|
@@ -0,0 +1,248 @@
|
|
1
|
+
// Include the Ruby headers
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "freeimage.h"
|
4
|
+
|
5
|
+
static VALUE rb_mGraffik;
|
6
|
+
static VALUE rb_cImage;
|
7
|
+
|
8
|
+
FIBITMAP *get_instance_image(VALUE self) {
|
9
|
+
FIBITMAP *image; // Place to store the image
|
10
|
+
Data_Get_Struct(self, FIBITMAP, image); // Load the image data from the instance
|
11
|
+
|
12
|
+
// Throw error if the image has already been closed
|
13
|
+
if (!image) {
|
14
|
+
rb_raise(rb_eTypeError, "Image has already been closed");
|
15
|
+
}
|
16
|
+
|
17
|
+
return image;
|
18
|
+
}
|
19
|
+
|
20
|
+
VALUE rb_graffik_close(VALUE self) {
|
21
|
+
FIBITMAP *image = get_instance_image(self);
|
22
|
+
FreeImage_Unload(image); // Free the image from memory
|
23
|
+
DATA_PTR(self) = NULL; // Release the data for Ruby
|
24
|
+
return Qnil; // Return nil back
|
25
|
+
}
|
26
|
+
|
27
|
+
VALUE rb_graffik_crop(VALUE self, VALUE rb_left, VALUE rb_top, VALUE rb_right, VALUE rb_bottom) {
|
28
|
+
// Convert Ruby numbers to C numbers
|
29
|
+
int top = FIX2INT(rb_top), right = FIX2INT(rb_right), bottom = FIX2INT(rb_bottom), left = FIX2INT(rb_left);
|
30
|
+
// Load our image and specifiy where to put the copy
|
31
|
+
FIBITMAP *image = get_instance_image(self);
|
32
|
+
// Crop the image
|
33
|
+
FIBITMAP *cropped = FreeImage_Copy(image, left, top, right, bottom);
|
34
|
+
// Create a new instance for Ruby
|
35
|
+
VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, cropped);
|
36
|
+
rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
|
37
|
+
|
38
|
+
// If a block is given, yield to it, if not, return the instance
|
39
|
+
if (rb_block_given_p()) {
|
40
|
+
return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
|
41
|
+
} else {
|
42
|
+
return instance;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
VALUE rb_graffik_cropped_thumbnail(VALUE self, VALUE rb_size) {
|
47
|
+
// Convert the Ruby numbers to C numbers
|
48
|
+
int size = FIX2INT(rb_size);
|
49
|
+
// Load our image
|
50
|
+
FIBITMAP *image = get_instance_image(self);
|
51
|
+
// Get dimensions
|
52
|
+
int width = FreeImage_GetWidth(image), height = FreeImage_GetHeight(image);
|
53
|
+
int left = 0, top = 0, right = width, bottom = height;
|
54
|
+
int half = (width - height) / 2;
|
55
|
+
|
56
|
+
if (width > height) {
|
57
|
+
left = half;
|
58
|
+
right = half + height;
|
59
|
+
}
|
60
|
+
|
61
|
+
if (height > width) {
|
62
|
+
top = half;
|
63
|
+
bottom = half + width;
|
64
|
+
}
|
65
|
+
|
66
|
+
// Crop the image
|
67
|
+
FIBITMAP *cropped = FreeImage_Copy(image, left, top, right, bottom);
|
68
|
+
// Resize the image
|
69
|
+
FIBITMAP *thumbnail = FreeImage_MakeThumbnail(cropped, size, TRUE);
|
70
|
+
// Create a new instance for Ruby
|
71
|
+
VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, thumbnail);
|
72
|
+
rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
|
73
|
+
|
74
|
+
// If a block is given, yield to it, if not, return the instance
|
75
|
+
if (rb_block_given_p()) {
|
76
|
+
return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
|
77
|
+
} else {
|
78
|
+
return instance;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
VALUE rb_graffik_from_memory(VALUE self, VALUE rb_data) {
|
83
|
+
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
84
|
+
Check_Type(rb_data, T_STRING);
|
85
|
+
|
86
|
+
// Get info about our in-memory image
|
87
|
+
BYTE *data_ptr = (BYTE *) RSTRING_PTR(rb_data);
|
88
|
+
DWORD data_length = RSTRING_LEN(rb_data);
|
89
|
+
|
90
|
+
// Open up the memory stream
|
91
|
+
FIMEMORY *stream = FreeImage_OpenMemory(data_ptr, data_length);
|
92
|
+
|
93
|
+
// Make sure the stream was open
|
94
|
+
if (stream == NULL) {
|
95
|
+
rb_raise(rb_eTypeError, "Unable to read image from memory");
|
96
|
+
}
|
97
|
+
|
98
|
+
fif = FreeImage_GetFileTypeFromMemory(stream, 0);
|
99
|
+
if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
|
100
|
+
int flags = ((fif == FIF_JPEG) ? JPEG_ACCURATE : 0);
|
101
|
+
// Load the image from disk
|
102
|
+
FIBITMAP *image = FreeImage_LoadFromMemory(fif, stream, flags);
|
103
|
+
// Release memory
|
104
|
+
FreeImage_CloseMemory(stream);
|
105
|
+
// Develop an instance for Ruby
|
106
|
+
VALUE instance = Data_Wrap_Struct(self, NULL, NULL, image);
|
107
|
+
// Store the image type as a FixNum
|
108
|
+
rb_iv_set(instance, "@file_type", INT2FIX(fif));
|
109
|
+
|
110
|
+
// If a block is given, yield to it, if not, return the instance
|
111
|
+
if (rb_block_given_p()) {
|
112
|
+
return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
|
113
|
+
} else {
|
114
|
+
return instance;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
// If we couldn't load it, throw and error
|
119
|
+
rb_raise(rb_eTypeError, "Unknown file format");
|
120
|
+
}
|
121
|
+
|
122
|
+
VALUE rb_graffik_height(VALUE self) {
|
123
|
+
FIBITMAP *image = get_instance_image(self);
|
124
|
+
int height = FreeImage_GetHeight(image); // Height from FreeImage
|
125
|
+
|
126
|
+
return INT2FIX(height);
|
127
|
+
}
|
128
|
+
|
129
|
+
VALUE rb_graffik_open(VALUE self, VALUE rb_filename) {
|
130
|
+
char *filename = STR2CSTR(rb_filename);
|
131
|
+
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
132
|
+
|
133
|
+
// Try various methods to thet the image format
|
134
|
+
fif = FreeImage_GetFileType(filename, 0);
|
135
|
+
if (fif == FIF_UNKNOWN) {
|
136
|
+
fif = FreeImage_GetFIFFromFilename(filename);
|
137
|
+
}
|
138
|
+
|
139
|
+
if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
|
140
|
+
int flags = ((fif == FIF_JPEG) ? JPEG_ACCURATE : 0);
|
141
|
+
// Load the image from disk
|
142
|
+
FIBITMAP *image = FreeImage_Load(fif, filename, flags);
|
143
|
+
// Develop an instance for Ruby
|
144
|
+
VALUE instance = Data_Wrap_Struct(self, NULL, NULL, image);
|
145
|
+
// Store the image type as a FixNum
|
146
|
+
rb_iv_set(instance, "@file_type", INT2FIX(fif));
|
147
|
+
|
148
|
+
// If a block is given, yield to it, if not, return the instance
|
149
|
+
if (rb_block_given_p()) {
|
150
|
+
return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
|
151
|
+
} else {
|
152
|
+
return instance;
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
// If we couldn't load it, throw and error
|
157
|
+
rb_raise(rb_eTypeError, "Unknown file format");
|
158
|
+
}
|
159
|
+
|
160
|
+
VALUE rb_graffik_resize(VALUE self, VALUE rb_width, VALUE rb_height) {
|
161
|
+
// Convert the Ruby numbers to C numbers
|
162
|
+
int width = FIX2INT(rb_width), height = FIX2INT(rb_height);
|
163
|
+
// Load our image
|
164
|
+
FIBITMAP *image = get_instance_image(self);
|
165
|
+
// Resize the image
|
166
|
+
FIBITMAP *resized = FreeImage_Rescale(image, width, height, FILTER_CATMULLROM);
|
167
|
+
// Create a new instance for Ruby
|
168
|
+
VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, resized);
|
169
|
+
rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
|
170
|
+
|
171
|
+
// If a block is given, yield to it, if not, return the instance
|
172
|
+
if (rb_block_given_p()) {
|
173
|
+
return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
|
174
|
+
} else {
|
175
|
+
return instance;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
VALUE rb_graffik_thumbnail(VALUE self, VALUE rb_size) {
|
180
|
+
// Convert the Ruby numbers to C numbers
|
181
|
+
int size = FIX2INT(rb_size);
|
182
|
+
// Load our image
|
183
|
+
FIBITMAP *image = get_instance_image(self);
|
184
|
+
// Resize the image
|
185
|
+
FIBITMAP *thumbnail = FreeImage_MakeThumbnail(image, size, TRUE);
|
186
|
+
// Create a new instance for Ruby
|
187
|
+
VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, thumbnail);
|
188
|
+
rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
|
189
|
+
|
190
|
+
// If a block is given, yield to it, if not, return the instance
|
191
|
+
if (rb_block_given_p()) {
|
192
|
+
return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
|
193
|
+
} else {
|
194
|
+
return instance;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
VALUE rb_graffik_width(VALUE self) {
|
199
|
+
FIBITMAP *image = get_instance_image(self);
|
200
|
+
int width = FreeImage_GetWidth(image); // Width from FreeImage
|
201
|
+
|
202
|
+
return INT2FIX(width);
|
203
|
+
}
|
204
|
+
|
205
|
+
VALUE rb_graffik_write(VALUE self, VALUE rb_filename) {
|
206
|
+
char *filename = STR2CSTR(rb_filename);
|
207
|
+
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
|
208
|
+
|
209
|
+
// Try various methods to get the image format
|
210
|
+
fif = FreeImage_GetFIFFromFilename(filename);
|
211
|
+
if (fif == FIF_UNKNOWN) {
|
212
|
+
fif = FIX2INT(rb_iv_get(self, "@file_type"));
|
213
|
+
}
|
214
|
+
|
215
|
+
if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsWriting(fif)) {
|
216
|
+
int flags = fif == FIF_JPEG ? JPEG_QUALITYSUPERB : 0;
|
217
|
+
// Load the image from the instance
|
218
|
+
FIBITMAP *image = get_instance_image(self);
|
219
|
+
|
220
|
+
// Return Ruby objects for the write status from FreeImage
|
221
|
+
return FreeImage_Save(fif, image, filename, flags) ? Qtrue : Qfalse;
|
222
|
+
}
|
223
|
+
|
224
|
+
rb_raise(rb_eTypeError, "Unknown file format");
|
225
|
+
}
|
226
|
+
|
227
|
+
// Intialize extension
|
228
|
+
void Init_graffik() {
|
229
|
+
// Define the Graffik module
|
230
|
+
rb_mGraffik = rb_define_module("Graffik");
|
231
|
+
|
232
|
+
// Image class
|
233
|
+
rb_cImage = rb_define_class_under(rb_mGraffik, "Image", rb_cObject);
|
234
|
+
|
235
|
+
// Image class methods
|
236
|
+
rb_define_singleton_method(rb_cImage, "open", rb_graffik_open, 1);
|
237
|
+
rb_define_singleton_method(rb_cImage, "from_memory", rb_graffik_from_memory, 1);
|
238
|
+
|
239
|
+
// Image instance methods
|
240
|
+
rb_define_method(rb_cImage, "crop", rb_graffik_crop, 4);
|
241
|
+
rb_define_method(rb_cImage, "cropped_thumbnail", rb_graffik_cropped_thumbnail, 1);
|
242
|
+
rb_define_method(rb_cImage, "close", rb_graffik_close, 0);
|
243
|
+
rb_define_method(rb_cImage, "height", rb_graffik_height, 0);
|
244
|
+
rb_define_method(rb_cImage, "resize", rb_graffik_resize, 2);
|
245
|
+
rb_define_method(rb_cImage, "thumbnail", rb_graffik_thumbnail, 1);
|
246
|
+
rb_define_method(rb_cImage, "width", rb_graffik_width, 0);
|
247
|
+
rb_define_method(rb_cImage, "write", rb_graffik_write, 1);
|
248
|
+
}
|
data/graffik.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{graffik}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jeremy Boles"]
|
12
|
+
s.date = %q{2010-06-01}
|
13
|
+
s.description = %q{Graffik is a Ruby wrapper for the FreeImage library.}
|
14
|
+
s.email = %q{jeremy@jeremyboles.com}
|
15
|
+
s.extensions = ["ext/graffik/extconf.rb"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"README.markdown",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"ext/graffik/extconf.rb",
|
24
|
+
"ext/graffik/graffik.c",
|
25
|
+
"graffik.gemspec"
|
26
|
+
]
|
27
|
+
s.homepage = %q{http://github.com/jeremyboles/Graffik}
|
28
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
s.rubygems_version = %q{1.3.7}
|
31
|
+
s.summary = %q{Graffik is a fast, light-weight image manipulation library.}
|
32
|
+
|
33
|
+
if s.respond_to? :specification_version then
|
34
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
35
|
+
s.specification_version = 3
|
36
|
+
|
37
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
38
|
+
else
|
39
|
+
end
|
40
|
+
else
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graffik
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jeremy Boles
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-06-01 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Graffik is a Ruby wrapper for the FreeImage library.
|
23
|
+
email: jeremy@jeremyboles.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions:
|
27
|
+
- ext/graffik/extconf.rb
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.markdown
|
30
|
+
files:
|
31
|
+
- README.markdown
|
32
|
+
- Rakefile
|
33
|
+
- VERSION
|
34
|
+
- ext/graffik/extconf.rb
|
35
|
+
- ext/graffik/graffik.c
|
36
|
+
- graffik.gemspec
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/jeremyboles/Graffik
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
hash: 3
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.7
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Graffik is a fast, light-weight image manipulation library.
|
71
|
+
test_files: []
|
72
|
+
|