Class: Graffik::Image

Inherits:
Object
  • Object
show all
Defined in:
ext/graffik/graffik.c

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_memory(rb_data) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'ext/graffik/graffik.c', line 82

VALUE rb_graffik_from_memory(VALUE self, VALUE rb_data) {
  FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
  Check_Type(rb_data, T_STRING);
  
  // Get info about our in-memory image
  BYTE *data_ptr = (BYTE *) RSTRING_PTR(rb_data);
  DWORD data_length = RSTRING_LEN(rb_data);
  
  // Open up the memory stream
  FIMEMORY *stream = FreeImage_OpenMemory(data_ptr, data_length);
  
  // Make sure the stream was open
  if (stream == NULL) {
    rb_raise(rb_eTypeError, "Unable to read image from memory");
  }
  
  fif = FreeImage_GetFileTypeFromMemory(stream, 0);
  if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
    int flags = ((fif == FIF_JPEG) ? JPEG_ACCURATE : 0);
    // Load the image from disk
    FIBITMAP *image = FreeImage_LoadFromMemory(fif, stream, flags);
    // Release memory
    FreeImage_CloseMemory(stream);
    // Develop an instance for Ruby
    VALUE instance = Data_Wrap_Struct(self, NULL, NULL, image);
    // Store the image type as a FixNum
    rb_iv_set(instance, "@file_type", INT2FIX(fif));
    
    // If a block is given, yield to it, if not, return the instance
    if (rb_block_given_p()) {
      return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
    } else {
      return instance;
    }
  }
  
  // If we couldn't load it, throw and error
  rb_raise(rb_eTypeError, "Unknown file format");
}

.open(rb_filename) ⇒ Object

Image class methods



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'ext/graffik/graffik.c', line 129

VALUE rb_graffik_open(VALUE self, VALUE rb_filename) {
  char *filename = STR2CSTR(rb_filename);
  FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
  
  // Try various methods to thet the image format
  fif = FreeImage_GetFileType(filename, 0);
  if (fif == FIF_UNKNOWN) {
    fif = FreeImage_GetFIFFromFilename(filename);
  }
  
  if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
    int flags = ((fif == FIF_JPEG) ? JPEG_ACCURATE : 0);
    // Load the image from disk
    FIBITMAP *image = FreeImage_Load(fif, filename, flags);
    // Develop an instance for Ruby
    VALUE instance = Data_Wrap_Struct(self, NULL, NULL, image);
    // Store the image type as a FixNum
    rb_iv_set(instance, "@file_type", INT2FIX(fif));
    
    // If a block is given, yield to it, if not, return the instance
    if (rb_block_given_p()) {
      return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
    } else {
      return instance;
    }
  }
  
  // If we couldn't load it, throw and error
  rb_raise(rb_eTypeError, "Unknown file format");
}

Instance Method Details

#closeObject



20
21
22
23
24
25
# File 'ext/graffik/graffik.c', line 20

VALUE rb_graffik_close(VALUE self) {
  FIBITMAP *image = get_instance_image(self);
  FreeImage_Unload(image); // Free the image from memory
  DATA_PTR(self) = NULL; // Release the data for Ruby
  return Qnil; // Return nil back
}

#crop(rb_left, rb_top, rb_right, rb_bottom) ⇒ Object

Return nil back



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'ext/graffik/graffik.c', line 27

VALUE rb_graffik_crop(VALUE self, VALUE rb_left, VALUE rb_top, VALUE rb_right, VALUE rb_bottom) {
  // Convert Ruby numbers to C numbers
  int top = FIX2INT(rb_top), right = FIX2INT(rb_right), bottom = FIX2INT(rb_bottom), left = FIX2INT(rb_left);
  // Load our image and specifiy where to put the copy
  FIBITMAP *image = get_instance_image(self);
  // Crop the image
  FIBITMAP *cropped = FreeImage_Copy(image, left, top, right, bottom);
  // Create a new instance for Ruby
  VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, cropped);
  rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
  
  // If a block is given, yield to it, if not, return the instance
  if (rb_block_given_p()) {
   return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
  } else {
   return instance;
  }
}

#cropped_thumbnail(rb_size) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'ext/graffik/graffik.c', line 46

VALUE rb_graffik_cropped_thumbnail(VALUE self, VALUE rb_size) {
  // Convert the Ruby numbers to C numbers
  int size = FIX2INT(rb_size);
  // Load our image
  FIBITMAP *image = get_instance_image(self);
  // Get dimensions
  int width = FreeImage_GetWidth(image), height = FreeImage_GetHeight(image);
  int left = 0, top = 0, right = width, bottom = height;
  int half = (width - height) / 2;
  
  if (width > height) {
    left = half;
    right = half + height;
  }
  
  if (height > width) {
    top = half;
    bottom = half + width;
  }
  
  // Crop the image
  FIBITMAP *cropped = FreeImage_Copy(image, left, top, right, bottom);
  // Resize the image
  FIBITMAP *thumbnail = FreeImage_MakeThumbnail(cropped, size, TRUE);
  // Create a new instance for Ruby
  VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, thumbnail);
  rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
   
   // If a block is given, yield to it, if not, return the instance
  if (rb_block_given_p()) {
    return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
  } else {
    return instance;
  }
}

#heightObject



122
123
124
125
126
127
# File 'ext/graffik/graffik.c', line 122

VALUE rb_graffik_height(VALUE self) {
  FIBITMAP *image = get_instance_image(self);
  int height = FreeImage_GetHeight(image); // Height from FreeImage
  
  return INT2FIX(height);
}

#resize(rb_width, rb_height) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'ext/graffik/graffik.c', line 160

VALUE rb_graffik_resize(VALUE self, VALUE rb_width, VALUE rb_height) {
  // Convert the Ruby numbers to C numbers
  int width = FIX2INT(rb_width), height = FIX2INT(rb_height);
  // Load our image
  FIBITMAP *image = get_instance_image(self);
  // Resize the image
  FIBITMAP *resized = FreeImage_Rescale(image, width, height, FILTER_CATMULLROM);
  // Create a new instance for Ruby
  VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, resized);
  rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
   
   // If a block is given, yield to it, if not, return the instance
  if (rb_block_given_p()) {
    return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
  } else {
    return instance;
  }
}

#thumbnail(rb_size) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'ext/graffik/graffik.c', line 179

VALUE rb_graffik_thumbnail(VALUE self, VALUE rb_size) {
  // Convert the Ruby numbers to C numbers
  int size = FIX2INT(rb_size);
  // Load our image
  FIBITMAP *image = get_instance_image(self);
  // Resize the image
  FIBITMAP *thumbnail = FreeImage_MakeThumbnail(image, size, TRUE);
  // Create a new instance for Ruby
  VALUE instance = Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, thumbnail);
  rb_iv_set(instance, "@file_type", rb_iv_get(self, "@file_type"));
   
   // If a block is given, yield to it, if not, return the instance
  if (rb_block_given_p()) {
    return rb_ensure(rb_yield, instance, rb_graffik_close, instance);
  } else {
    return instance;
  }
}

#widthObject



198
199
200
201
202
203
# File 'ext/graffik/graffik.c', line 198

VALUE rb_graffik_width(VALUE self) {
  FIBITMAP *image = get_instance_image(self);
  int width = FreeImage_GetWidth(image); // Width from FreeImage
  
  return INT2FIX(width);
}

#write(rb_filename) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'ext/graffik/graffik.c', line 205

VALUE rb_graffik_write(VALUE self, VALUE rb_filename) {
  char *filename = STR2CSTR(rb_filename);
  FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
  
  // Try various methods to get the image format
  fif = FreeImage_GetFIFFromFilename(filename);
  if (fif == FIF_UNKNOWN) {
    fif = FIX2INT(rb_iv_get(self, "@file_type"));
  }
  
  if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsWriting(fif)) {
    int flags = fif == FIF_JPEG ? JPEG_QUALITYSUPERB : 0;
    // Load the image from the instance
    FIBITMAP *image = get_instance_image(self);

    // Return Ruby objects for the write status from FreeImage
    return FreeImage_Save(fif, image, filename, flags) ? Qtrue : Qfalse;
  }
  
  rb_raise(rb_eTypeError, "Unknown file format");
}