Class: GD::Image
- Inherits:
-
Object
- Object
- GD::Image
- Defined in:
- ext/gd/image.c,
lib/gd.rb
Constant Summary collapse
- DEFAULT_FONT =
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"- DEFAULT_FONT_SIZE =
12
Class Method Summary collapse
Instance Method Summary collapse
- #alpha_blending=(flag) ⇒ Object
- #antialias(flag) ⇒ Object
- #antialias=(flag) ⇒ Object
- #arc(*args) ⇒ Object
- #circle(*args) ⇒ Object
- #clone ⇒ Object
- #copy ⇒ Object
- #copy_merge(src, dx, dy, sx, sy, w, h, pct) ⇒ Object
- #copy_resize(*args) ⇒ Object
- #crop(vx, vy, vw, vh) ⇒ Object
- #draw_string(x, y, text, color, size: DEFAULT_FONT_SIZE, font: DEFAULT_FONT) ⇒ Object
- #ellipse(*args) ⇒ Object
-
#fill(color) ⇒ Object
- x
-
imagefill — Flood fill.
- #filled_arc(*args) ⇒ Object
- #filled_circle(*args) ⇒ Object
- #filled_ellipse(*args) ⇒ Object
- #filled_polygon(points, color) ⇒ Object
- #filled_rectangle(*args) ⇒ Object
- #filter(*args) ⇒ Object
- #get_pixel(vx, vy) ⇒ Object
- #height ⇒ Object
- #initialize(*args) ⇒ Object constructor
- #line(*args) ⇒ Object
- #polygon(points, color) ⇒ Object
-
#rectangle(*args) ⇒ Object
-
imagerectangle — Draw a rectangle - [ ] imagefilledrectangle — Draw a filled rectangle.
- #resize(vw, vh) ⇒ Object
- #save(*args) ⇒ Object
- #save_alpha=(flag) ⇒ Object
- #scale(vw, vh) ⇒ Object
- #set_pixel(x, y, color) ⇒ Object
- #text(text, opts) ⇒ Object
- #text_bbox(text, opts) ⇒ Object
- #text_ft(text, opts) ⇒ Object
- #to_png ⇒ Object
- #width ⇒ Object
Constructor Details
#initialize(*args) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'ext/gd/image.c', line 3
static VALUE gd_image_initialize(int argc, VALUE *argv, VALUE self) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
wrap->img = NULL;
if (argc == 0) {
return self;
}
if (argc != 2) {
rb_raise(rb_eArgError, "expected 0 or 2 arguments");
}
int w = NUM2INT(argv[0]);
int h = NUM2INT(argv[1]);
if (w <= 0 || h <= 0)
rb_raise(rb_eArgError, "width and height must be positive");
wrap->img = gdImageCreateTrueColor(w,h);
gdImageSaveAlpha(wrap->img, 1);
gdImageAlphaBlending(wrap->img, 0);
int transparent = gdTrueColorAlpha(0,0,0,127);
gdImageFilledRectangle(wrap->img, 0,0,w,h, transparent);
gdImageAlphaBlending(wrap->img, 1);
int t = gdTrueColorAlpha(0,0,0,127);
gdImageFilledRectangle(wrap->img, 0, 0, w-1, h-1, t);
if (!wrap->img)
rb_raise(rb_eRuntimeError, "gdImageCreateTrueColor failed");
return self;
}
|
Class Method Details
.new_true_color(width, height) ⇒ Object
68 69 70 71 72 |
# File 'ext/gd/image.c', line 68
static VALUE gd_image_s_new_true_color(VALUE klass, VALUE width, VALUE height) {
VALUE obj = rb_class_new_instance(0, NULL, klass);
gd_image_initialize_true_color(obj, width, height);
return obj;
}
|
.open(path) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'ext/gd/image.c', line 119
static VALUE gd_image_open(VALUE klass, VALUE path) {
const char *filename = StringValueCStr(path);
FILE *f = fopen(filename, "rb");
if (!f) rb_sys_fail(filename);
gdImagePtr img = NULL;
const char *ext = strrchr(filename, '.');
if (!ext) rb_raise(rb_eArgError, "unknown image type");
if (strcmp(ext, ".png") == 0) {
img = gdImageCreateFromPng(f);
} else if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) {
img = gdImageCreateFromJpeg(f);
} else if (strcmp(ext, ".webp") == 0) {
img = gdImageCreateFromWebp(f);
} else if (strcmp(ext, ".gif") == 0) {
img = gdImageCreateFromGif(f);
} else {
fclose(f);
rb_raise(rb_eArgError, "unsupported format");
}
fclose(f);
if (!img) rb_raise(rb_eRuntimeError, "image decode failed");
VALUE obj = rb_class_new_instance(0, NULL, klass);
gd_image_wrapper *wrap;
TypedData_Get_Struct(obj, gd_image_wrapper, &gd_image_type, wrap);
wrap->img = img;
return obj;
}
|
Instance Method Details
#alpha_blending=(flag) ⇒ Object
154 155 156 157 158 159 160 |
# File 'ext/gd/image.c', line 154
static VALUE gd_image_alpha_blending(VALUE self, VALUE flag) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
gdImageAlphaBlending(wrap->img, RTEST(flag));
return self;
}
|
#antialias(flag) ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'ext/gd/image.c', line 251
static VALUE gd_image_antialias(VALUE self, VALUE flag) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
if (!wrap->img)
rb_raise(rb_eRuntimeError, "image is NULL");
if (RTEST(flag)) {
int aa = gdTrueColorAlpha(255,255,255,0);
gdImageSetAntiAliased(wrap->img, aa);
gdImageAlphaBlending(wrap->img, 1);
} else {
gdImageSetAntiAliased(wrap->img, -1);
}
return flag;
}
|
#antialias=(flag) ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'ext/gd/image.c', line 251
static VALUE gd_image_antialias(VALUE self, VALUE flag) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
if (!wrap->img)
rb_raise(rb_eRuntimeError, "image is NULL");
if (RTEST(flag)) {
int aa = gdTrueColorAlpha(255,255,255,0);
gdImageSetAntiAliased(wrap->img, aa);
gdImageAlphaBlending(wrap->img, 1);
} else {
gdImageSetAntiAliased(wrap->img, -1);
}
return flag;
}
|
#arc(*args) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'ext/gd/arc.c', line 3
static VALUE
gd_image_arc(int argc, VALUE *argv, VALUE self)
{
VALUE vcx, vcy, vw, vh, vstart, vend, vcolor, opts;
VALUE thickness = Qnil;
opts = Qnil;
rb_scan_args(argc, argv, "7:", &vcx, &vcy, &vw, &vh, &vstart, &vend, &vcolor, &opts);
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int cx = NUM2INT(vcx);
int cy = NUM2INT(vcy);
int w = NUM2INT(vw);
int h = NUM2INT(vh);
int s = NUM2INT(vstart);
int e = NUM2INT(vend);
int c = color_to_gd(wrap->img, vcolor);
int t = NIL_P(thickness) ? 1 : NUM2INT(thickness);
int half = t / 2;
for (int i = -half; i <= half; i++) {
gdImageArc(wrap->img, cx + i, cy, w, h, s, e, c);
}
return self;
}
|
#circle(*args) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'ext/gd/circle.c', line 3
static VALUE gd_image_circle(int argc, VALUE *argv, VALUE self)
{
VALUE vcx, vcy, vradius, vcolor, opts;
VALUE thickness = Qnil;
opts = Qnil;
rb_scan_args(argc, argv, "4:", &vcx, &vcy, &vradius, &vcolor, &opts);
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int cx = NUM2INT(vcx);
int cy = NUM2INT(vcy);
int r = NUM2INT(vradius);
int c = color_to_gd(wrap->img, vcolor);
int t = NIL_P(thickness) ? 1 : NUM2INT(thickness);
int half = t / 2;
for (int i = -half; i <= half; i++) {
gdImageArc(wrap->img,
cx, cy,
(r + i) * 2, (r + i) * 2,
0, 360,
c);
}
return self;
}
|
#clone ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'ext/gd/image.c', line 74
static VALUE gd_image_clone(VALUE self) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
if (!wrap->img) rb_raise(rb_eRuntimeError, "cannot clone: image is NULL");
gdImagePtr copy = gdImageClone(wrap->img);
if (!copy) rb_raise(rb_eRuntimeError, "gdImageClone failed");
VALUE obj = rb_class_new_instance(0, NULL, CLASS_OF(self));
gd_image_wrapper *w2;
TypedData_Get_Struct(obj, gd_image_wrapper, &gd_image_type, w2);
w2->img = copy;
return obj;
}
|
#copy ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'ext/gd/image.c', line 182
static VALUE gd_image_copy (
VALUE self, VALUE src,
VALUE dx, VALUE dy,
VALUE sx, VALUE sy,
VALUE w, VALUE h
) {
gd_image_wrapper *dst;
gd_image_wrapper *srcw;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, dst);
TypedData_Get_Struct(src, gd_image_wrapper, &gd_image_type, srcw);
gdImageCopy(
dst->img,
srcw->img,
NUM2INT(dx), NUM2INT(dy),
NUM2INT(sx), NUM2INT(sy),
NUM2INT(w), NUM2INT(h)
);
return Qnil;
}
|
#copy_merge(src, dx, dy, sx, sy, w, h, pct) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'ext/gd/blit.c', line 10
static VALUE gd_image_copy_merge(
VALUE self, VALUE src,
VALUE dx, VALUE dy,
VALUE sx, VALUE sy,
VALUE w, VALUE h,
VALUE pct
) {
gd_image_wrapper *dst_wrap;
gd_image_wrapper *src_wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, dst_wrap);
TypedData_Get_Struct(src, gd_image_wrapper, &gd_image_type, src_wrap);
gdImageCopyMerge(
dst_wrap->img,
src_wrap->img,
NUM2INT(dx), NUM2INT(dy),
NUM2INT(sx), NUM2INT(sy),
NUM2INT(w), NUM2INT(h),
NUM2INT(pct)
);
return self;
}
|
#copy_resize(*args) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'ext/gd/image.c', line 205
static VALUE gd_image_copy_resize(int argc, VALUE *argv, VALUE self) {
VALUE src_img;
VALUE dst_x, dst_y, src_x, src_y, src_w, src_h, dst_w, dst_h, resample;
rb_scan_args(argc, argv, "91",
&src_img, &dst_x, &dst_y, &src_x, &src_y,
&src_w, &src_h, &dst_w, &dst_h,
&resample
);
gd_image_wrapper *dst, *src;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, dst);
TypedData_Get_Struct(src_img, gd_image_wrapper, &gd_image_type, src);
int dx = NUM2INT(dst_x);
int dy = NUM2INT(dst_y);
int sx = NUM2INT(src_x);
int sy = NUM2INT(src_y);
int sw = NUM2INT(src_w);
int sh = NUM2INT(src_h);
int dw = NUM2INT(dst_w);
int dh = NUM2INT(dst_h);
int do_resample = RTEST(resample);
if (do_resample) {
gdImageCopyResampled(
dst->img, src->img,
dx, dy,
sx, sy,
dw, dh,
sw, sh
);
} else {
gdImageCopyResized(
dst->img, src->img,
dx, dy,
sx, sy,
dw, dh,
sw, sh
);
}
return self;
}
|
#crop(vx, vy, vw, vh) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'ext/gd/transform.c', line 11
static VALUE gd_image_crop(VALUE self, VALUE vx, VALUE vy, VALUE vw, VALUE vh) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
gdRect r;
r.x = NUM2INT(vx);
r.y = NUM2INT(vy);
r.width = NUM2INT(vw);
r.height = NUM2INT(vh);
gdImagePtr out = gdImageCrop(wrap->img, &r);
if (!out) rb_raise(rb_eRuntimeError, "crop failed");
return wrap_new_image(out, CLASS_OF(self));
}
|
#draw_string(x, y, text, color, size: DEFAULT_FONT_SIZE, font: DEFAULT_FONT) ⇒ Object
7 8 9 10 11 12 13 14 15 |
# File 'lib/gd.rb', line 7 def draw_string(x, y, text, color, size: DEFAULT_FONT_SIZE, font: DEFAULT_FONT) self.text(text, { x: x, y: y, size: size, color: color, font: font }) end |
#ellipse(*args) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'ext/gd/ellipse.c', line 7
static VALUE gd_image_ellipse(int argc, VALUE *argv, VALUE self)
{
VALUE vcx, vcy, vw, vh, vcolor, opts;
VALUE thickness = Qnil;
opts = Qnil;
rb_scan_args(argc, argv, "5:", &vcx, &vcy, &vw, &vh, &vcolor, &opts);
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int cx = NUM2INT(vcx);
int cy = NUM2INT(vcy);
int w = NUM2INT(vw);
int h = NUM2INT(vh);
int c = color_to_gd(wrap->img, vcolor);
int t = NIL_P(thickness) ? 1 : NUM2INT(thickness);
int half = t / 2;
for (int i = -half; i <= half; i++) {
gdImageArc(wrap->img,
cx, cy,
w + i * 2, h + i * 2,
0, 360,
c);
}
return self;
}
|
#fill(color) ⇒ Object
- x
-
imagefill — Flood fill
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'ext/gd/fill.c', line 6
static VALUE gd_image_fill(VALUE self, VALUE color) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
if (!wrap || !wrap->img)
rb_raise(rb_eRuntimeError, "uninitialized GD::Image");
int c = color_to_gd(wrap->img, color);
gdImageFilledRectangle(
wrap->img,
0, 0,
gdImageSX(wrap->img) - 1,
gdImageSY(wrap->img) - 1,
c
);
return self;
}
|
#filled_arc(*args) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'ext/gd/arc.c', line 37
static VALUE
gd_image_filled_arc(int argc, VALUE *argv, VALUE self)
{
VALUE vcx, vcy, vw, vh, vstart, vend, vcolor;
rb_scan_args(argc, argv, "7", &vcx, &vcy, &vw, &vh, &vstart, &vend, &vcolor);
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int cx = NUM2INT(vcx);
int cy = NUM2INT(vcy);
int w = NUM2INT(vw);
int h = NUM2INT(vh);
int s = NUM2INT(vstart);
int e = NUM2INT(vend);
int c = color_to_gd(wrap->img, vcolor);
gdImageFilledArc(wrap->img, cx, cy, w, h, s, e, c, gdArc);
return self;
}
|
#filled_circle(*args) ⇒ Object
37 38 39 40 41 42 43 44 45 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 |
# File 'ext/gd/circle.c', line 37
static VALUE gd_image_filled_circle(int argc, VALUE *argv, VALUE self)
{
VALUE vcx, vcy, vradius, vcolor, opts;
VALUE thickness = Qnil;
opts = Qnil;
rb_scan_args(argc, argv, "4:", &vcx, &vcy, &vradius, &vcolor, &opts);
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int cx = NUM2INT(vcx);
int cy = NUM2INT(vcy);
int r = NUM2INT(vradius);
int c = color_to_gd(wrap->img, vcolor);
/* Fill */
gdImageFilledEllipse(wrap->img,
cx, cy,
r * 2, r * 2,
c);
/* Stroke */
int t = NIL_P(thickness) ? 1 : NUM2INT(thickness);
int half = t / 2;
for (int i = -half; i <= half; i++) {
gdImageArc(wrap->img,
cx, cy,
(r + i) * 2, (r + i) * 2,
0, 360,
c);
}
return self;
}
|
#filled_ellipse(*args) ⇒ Object
42 43 44 45 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 |
# File 'ext/gd/ellipse.c', line 42
static VALUE gd_image_filled_ellipse(int argc, VALUE *argv, VALUE self)
{
VALUE vcx, vcy, vw, vh, vcolor, opts;
VALUE thickness = Qnil;
opts = Qnil;
rb_scan_args(argc, argv, "5:", &vcx, &vcy, &vw, &vh, &vcolor, &opts);
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int cx = NUM2INT(vcx);
int cy = NUM2INT(vcy);
int w = NUM2INT(vw);
int h = NUM2INT(vh);
int c = color_to_gd(wrap->img, vcolor);
/* Fill */
gdImageFilledEllipse(wrap->img, cx, cy, w, h, c);
/* Stroke */
int t = NIL_P(thickness) ? 1 : NUM2INT(thickness);
int half = t / 2;
for (int i = -half; i <= half; i++) {
gdImageArc(wrap->img,
cx, cy,
w + i * 2, h + i * 2,
0, 360,
c);
}
return self;
}
|
#filled_polygon(points, color) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'ext/gd/polygon.c', line 72
static VALUE gd_image_filled_polygon(VALUE self, VALUE points, VALUE color) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
if (!wrap || !wrap->img) {
rb_raise(rb_eRuntimeError, "uninitialized GD::Image");
}
int count = 0;
gdPointPtr pts = build_points(points, &count);
if (!pts || count < 3) {
if (pts) xfree(pts);
rb_raise(rb_eArgError, "points must be an Array of at least 3 [x,y] pairs");
}
int c = color_to_gd(wrap->img, color);
gdImageFilledPolygon(wrap->img, pts, count, c);
xfree(pts);
return self;
}
|
#filled_rectangle(*args) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'ext/gd/rectangle.c', line 32
static VALUE gd_image_filled_rectangle(int argc, VALUE *argv, VALUE self) {
VALUE x1, y1, x2, y2, color, opts;
VALUE thickness = Qnil;
opts = Qnil;
rb_scan_args(argc, argv, "5:", &x1, &y1, &x2, &y2, &color, &opts);
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int c = color_to_gd(wrap->img, color);
if (!NIL_P(thickness)) {
gdImageSetThickness(wrap->img, NUM2INT(thickness));
}
gdImageFilledRectangle(wrap->img,
NUM2INT(x1), NUM2INT(y1),
NUM2INT(x2), NUM2INT(y2),
c);
gdImageSetThickness(wrap->img, 1);
return Qnil;
}
|
#filter(*args) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 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 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'ext/gd/filter.c', line 27
static VALUE gd_image_filter(int argc, VALUE *argv, VALUE self) {
VALUE type, arg1, arg2, arg3, arg4;
rb_scan_args(argc, argv, "14", &type, &arg1, &arg2, &arg3, &arg4);
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
type = rb_obj_as_string(type);
const char *name = StringValueCStr(type);
if (strcmp(name, "negate") == 0) {
gdImageNegate(wrap->img);
}
else if (strcmp(name, "grayscale") == 0) {
gdImageGrayScale(wrap->img);
}
else if (strcmp(name, "brightness") == 0) {
gdImageBrightness(wrap->img, NUM2INT(arg1));
}
else if (strcmp(name, "contrast") == 0) {
gdImageContrast(wrap->img, NUM2INT(arg1));
}
else if (strcmp(name, "colorize") == 0) {
rb_raise(rb_eNotImpError, "colorize not supported by libgd");
}
else if (strcmp(name, "edge_detect") == 0) {
gdImageEdgeDetectQuick(wrap->img);
}
else if (strcmp(name, "emboss") == 0) {
gdImageEmboss(wrap->img);
}
else if (strcmp(name, "gaussian_blur") == 0) {
gdImageGaussianBlur(wrap->img);
}
else if (strcmp(name, "selective_blur") == 0) {
gdImageSelectiveBlur(wrap->img);
}
else if (strcmp(name, "mean_removal") == 0) {
gdImageMeanRemoval(wrap->img);
}
else if (strcmp(name, "smooth") == 0) {
gdImageSmooth(wrap->img, NUM2INT(arg1));
}
else if (strcmp(name, "pixelate") == 0) {
gdImagePixelate(
wrap->img,
NUM2INT(arg1),
RTEST(arg2)
);
}
else if (strcmp(name, "scatter") == 0) {
gdImageScatter(
wrap->img,
NUM2INT(arg1),
NUM2INT(arg2)
);
}
else if (strcmp(name, "sepia") == 0) {
gd_image_apply_sepia(wrap->img);
}
else {
rb_raise(rb_eArgError, "unknown filter");
}
return self;
}
|
#get_pixel(vx, vy) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'ext/gd/pixel.c', line 14
static VALUE gd_image_get_pixel(VALUE self, VALUE vx, VALUE vy) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int x = NUM2INT(vx);
int y = NUM2INT(vy);
if (!wrap || !wrap->img) rb_raise(rb_eRuntimeError, "uninitialized GD::Image");
int p = gdImageGetTrueColorPixel(wrap->img, x, y);
int r = gdTrueColorGetRed(p);
int g = gdTrueColorGetGreen(p);
int b = gdTrueColorGetBlue(p);
int a = gdTrueColorGetAlpha(p);
VALUE ary = rb_ary_new_capa(4);
rb_ary_push(ary, INT2NUM(r));
rb_ary_push(ary, INT2NUM(g));
rb_ary_push(ary, INT2NUM(b));
rb_ary_push(ary, INT2NUM(a));
return ary;
}
|
#height ⇒ Object
176 177 178 179 180 |
# File 'ext/gd/image.c', line 176
static VALUE gd_image_height(VALUE self) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
return INT2NUM(gdImageSY(wrap->img));
}
|
#line(*args) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'ext/gd/draw_line.c', line 5
static VALUE gd_image_line(int argc, VALUE *argv, VALUE self) {
VALUE x1, y1, x2, y2, color, opts;
opts = Qnil;
rb_scan_args(argc, argv, "5:", &x1, &y1, &x2, &y2, &color, &opts);
VALUE thickness = Qnil;
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int ix1 = NUM2INT(x1);
int iy1 = NUM2INT(y1);
int ix2 = NUM2INT(x2);
int iy2 = NUM2INT(y2);
int ox1 = ix1;
int oy1 = iy1;
int ox2 = ix2;
int oy2 = iy2;
int w = wrap->img->sx;
int h = wrap->img->sy;
/* Clip to image bounds */
int xmin = 0;
int ymin = 0;
int xmax = w - 1;
int ymax = h - 1;
if (!gd_clip_line_to_rect(&ix1, &iy1, &ix2, &iy2, xmin, ymin, xmax, ymax)) {
rb_warn("Line is completely outside image bounds");
return Qnil;
}
if (ix1 != ox1 || iy1 != oy1 || ix2 != ox2 || iy2 != oy2) {
rb_warn("Line coordinates clipped to image bounds");
}
if (TYPE(color) != T_ARRAY || RARRAY_LEN(color) < 3 || RARRAY_LEN(color) > 4) {
rb_raise(rb_eArgError, "color must be [r,g,b] or [r,g,b,a]");
}
int c = color_to_gd(wrap->img, color);
int old = 1;
if (!NIL_P(thickness)) {
gdImageSetThickness(wrap->img, NUM2INT(thickness));
}
gdImageLine(wrap->img, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), c);
gdImageSetThickness(wrap->img, old);
return Qnil;
}
|
#polygon(points, color) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'ext/gd/polygon.c', line 58
static VALUE gd_image_polygon(VALUE self, VALUE points, VALUE color) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int count = 0;
gdPointPtr pts = build_points(points, &count);
int c = color_to_gd(wrap->img, color);
gdImagePolygon(wrap->img, pts, count, c);
xfree(pts);
return self;
}
|
#rectangle(*args) ⇒ Object
-
imagerectangle — Draw a rectangle
-
imagefilledrectangle — Draw a filled rectangle
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'ext/gd/rectangle.c', line 6
static VALUE gd_image_rectangle(int argc, VALUE *argv, VALUE self) {
VALUE x1, y1, x2, y2, color, opts;
VALUE thickness = Qnil;
opts = Qnil;
rb_scan_args(argc, argv, "5:", &x1, &y1, &x2, &y2, &color, &opts);
if (!NIL_P(opts)) {
thickness = rb_hash_aref(opts, ID2SYM(rb_intern("thickness")));
}
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int c = color_to_gd(wrap->img, color);
if (!NIL_P(thickness)) {
gdImageSetThickness(wrap->img, NUM2INT(thickness));
}
gdImageRectangle(wrap->img,
NUM2INT(x1), NUM2INT(y1),
NUM2INT(x2), NUM2INT(y2),
c);
gdImageSetThickness(wrap->img, 1);
return Qnil;
}
|
#resize(vw, vh) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'ext/gd/transform.c', line 27
static VALUE gd_image_scale(VALUE self, VALUE vw, VALUE vh) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int w = NUM2INT(vw);
int h = NUM2INT(vh);
gdImagePtr out = gdImageScale(wrap->img, w, h);
if (!out) rb_raise(rb_eRuntimeError, "scale failed");
return wrap_new_image(out, CLASS_OF(self));
}
|
#save(*args) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'ext/gd/encode.c', line 3
static VALUE gd_image_save(int argc, VALUE *argv, VALUE self) {
VALUE path, opts;
rb_scan_args(argc, argv, "11", &path, &opts);
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
const char *filename = StringValueCStr(path);
const char *ext = strrchr(filename, '.');
if (!ext) rb_raise(rb_eArgError, "file extension required");
FILE *f = fopen(filename, "wb");
if (!f) rb_sys_fail(filename);
if (strcmp(ext, ".png") == 0) {
gdImageSaveAlpha(wrap->img, 1);
gdImageAlphaBlending(wrap->img, 0);
gdImagePng(wrap->img, f);
} else if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) {
int quality = 90;
if (opts != Qnil) {
VALUE q = rb_hash_aref(opts, ID2SYM(rb_intern("quality")));
if (!NIL_P(q)) quality = NUM2INT(q);
}
gdImageJpeg(wrap->img, f, quality);
} else if (strcmp(ext, ".webp") == 0) {
gdImageWebp(wrap->img, f);
} else {
fclose(f);
rb_raise(rb_eArgError, "unsupported format");
}
fclose(f);
return Qtrue;
}
|
#save_alpha=(flag) ⇒ Object
162 163 164 165 166 167 168 |
# File 'ext/gd/image.c', line 162
static VALUE gd_image_save_alpha(VALUE self, VALUE flag) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
gdImageSaveAlpha(wrap->img, RTEST(flag));
return self;
}
|
#scale(vw, vh) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'ext/gd/transform.c', line 27
static VALUE gd_image_scale(VALUE self, VALUE vw, VALUE vh) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int w = NUM2INT(vw);
int h = NUM2INT(vh);
gdImagePtr out = gdImageScale(wrap->img, w, h);
if (!out) rb_raise(rb_eRuntimeError, "scale failed");
return wrap_new_image(out, CLASS_OF(self));
}
|
#set_pixel(x, y, color) ⇒ Object
3 4 5 6 7 8 9 10 11 12 |
# File 'ext/gd/pixel.c', line 3
static VALUE gd_image_set_pixel(VALUE self, VALUE x, VALUE y, VALUE color) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int c = color_to_gd(wrap->img, color);
gdImageSetPixel(wrap->img, NUM2INT(x), NUM2INT(y), c);
return Qnil;
}
|
#text(text, opts) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'ext/gd/text.c', line 3
static VALUE gd_image_text(VALUE self, VALUE text, VALUE opts) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
VALUE x = rb_hash_aref(opts, ID2SYM(rb_intern("x")));
VALUE y = rb_hash_aref(opts, ID2SYM(rb_intern("y")));
VALUE size = rb_hash_aref(opts, ID2SYM(rb_intern("size")));
VALUE color = rb_hash_aref(opts, ID2SYM(rb_intern("color")));
VALUE font = rb_hash_aref(opts, ID2SYM(rb_intern("font")));
if (NIL_P(x) || NIL_P(y) || NIL_P(size) || NIL_P(color) || NIL_P(font))
rb_raise(rb_eArgError, "missing options");
int fg = color_to_gd(wrap->img, color);
int brect[8];
char *err = gdImageStringFT(
wrap->img,
brect,
fg,
StringValueCStr(font),
NUM2DBL(size),
0,
NUM2INT(x),
NUM2INT(y),
StringValueCStr(text)
);
if (err) rb_raise(rb_eRuntimeError, "%s", err);
return Qnil;
}
|
#text_bbox(text, opts) ⇒ Object
36 37 38 39 40 41 42 43 44 45 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/gd/text.c', line 36
static VALUE gd_image_text_bbox(VALUE self, VALUE text, VALUE opts) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
VALUE fontV = rb_hash_aref(opts, ID2SYM(rb_intern("font")));
VALUE sizeV = rb_hash_aref(opts, ID2SYM(rb_intern("size")));
if (NIL_P(fontV) || NIL_P(sizeV))
rb_raise(rb_eArgError, "font and size are required");
VALUE angleV = rb_hash_aref(opts, ID2SYM(rb_intern("angle")));
double angle = NIL_P(angleV) ? 0.0 : NUM2DBL(angleV);
const char *font = StringValueCStr(fontV);
const char *str = StringValueCStr(text);
double size = NUM2DBL(sizeV);
int brect[8];
gdFTStringExtra extra;
memset(&extra, 0, sizeof(extra));
char *err = gdImageStringFTEx(
wrap->img,
brect,
0, /* no color, we don't draw */
font,
size,
angle,
0,
0,
str,
&extra
);
if (err) rb_raise(rb_eRuntimeError, "%s", err);
int w = brect[2] - brect[0];
int h = brect[1] - brect[7];
VALUE ary = rb_ary_new2(2);
rb_ary_push(ary, INT2NUM(w));
rb_ary_push(ary, INT2NUM(h));
return ary;
}
|
#text_ft(text, opts) ⇒ Object
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'ext/gd/text.c', line 83
static VALUE gd_image_text_ft(VALUE self, VALUE text, VALUE opts) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
VALUE xV = rb_hash_aref(opts, ID2SYM(rb_intern("x")));
VALUE yV = rb_hash_aref(opts, ID2SYM(rb_intern("y")));
VALUE sizeV = rb_hash_aref(opts, ID2SYM(rb_intern("size")));
VALUE colorV = rb_hash_aref(opts, ID2SYM(rb_intern("color")));
VALUE fontV = rb_hash_aref(opts, ID2SYM(rb_intern("font")));
if (NIL_P(xV)||NIL_P(yV)||NIL_P(sizeV)||NIL_P(colorV)||NIL_P(fontV))
rb_raise(rb_eArgError, "missing required options");
int x = NUM2INT(xV);
int y = NUM2INT(yV);
double size = NUM2DBL(sizeV);
const char *font = StringValueCStr(fontV);
const char *str = StringValueCStr(text);
VALUE angleV = rb_hash_aref(opts, ID2SYM(rb_intern("angle")));
double angle = NIL_P(angleV) ? 0.0 : NUM2DBL(angleV);
VALUE dpiV = rb_hash_aref(opts, ID2SYM(rb_intern("dpi")));
int dpi = NIL_P(dpiV) ? 96 : NUM2INT(dpiV);
//
VALUE lsV = rb_hash_aref(opts, ID2SYM(rb_intern("line_spacing")));
double ls = NIL_P(lsV) ? 1.0 : NUM2DBL(lsV);
int fg = color_to_gd(wrap->img, colorV);
gdFTStringExtra extra;
memset(&extra, 0, sizeof(extra));
extra.flags = gdFTEX_LINESPACE | gdFTEX_RESOLUTION;
extra.linespacing = ls;
extra.hdpi = dpi;
extra.vdpi = dpi;
char *err = gdImageStringFTEx(
wrap->img,
NULL,
fg,
font,
size,
angle,
x,
y,
str,
&extra
);
if (err) rb_raise(rb_eRuntimeError, "%s", err);
return Qnil;
}
|
#to_png ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'ext/gd/encode.c', line 40
static VALUE gd_image_to_png(VALUE self) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
int size = 0;
void *data = gdImagePngPtr(wrap->img, &size);
if (!data) rb_raise(rb_eRuntimeError, "PNG encode failed");
VALUE str = rb_str_new((const char*)data, size);
gdFree(data);
return str;
}
|
#width ⇒ Object
170 171 172 173 174 |
# File 'ext/gd/image.c', line 170
static VALUE gd_image_width(VALUE self) {
gd_image_wrapper *wrap;
TypedData_Get_Struct(self, gd_image_wrapper, &gd_image_type, wrap);
return INT2NUM(gdImageSX(wrap->img));
}
|