graffik 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|