Class: Ray::Image

Inherits:
Object
  • Object
show all
Extended by:
ResourceSet
Includes:
Enumerable, PP
Defined in:
ext/image.c,
lib/ray/image.rb,
lib/ray/turtle.rb,
ext/image.c

Overview

An image is a bidimensonial array of pixels used to texture rendering. It is not an object you can draw per se. See Sprite or more generically Drawable for this.

You can directly access pixels of an image, but an image target (ImageTarget) must be used to be able to draw more complex objects on it.

Iterating over an image collapse

Instance Method Summary collapse

Methods included from ResourceSet

add_set, clear, missing_pattern, reject!, select!, set_hash

Methods included from PP

#pretty_print_attributes

Constructor Details

#initialize(io) ⇒ Object #initialize(filename) ⇒ Object #initialize(size) ⇒ Object

Overloads:

  • #initialize(io) ⇒ Object

    Creates an image from an IO object

    Examples:

    open("test.png") { |io| Ray::Image.new(io) }

    Parameters:

    • io (IO, #read)

      An object containing the image.

  • #initialize(filename) ⇒ Object

    Loads an image from a file

    Examples:

    Ray::Image.new "test.png"

    Parameters:

    • filename (String)

      Name of a file to load the image from.

  • #initialize(size) ⇒ Object

    Creates an image from a size

    Examples:

    Ray::Image.new [64, 128]

    Parameters:

    • size (Vector2, #to_vector2)

      Size of the image to create



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'ext/image.c', line 42

static
VALUE ray_image_init(VALUE self, VALUE arg) {
  say_image *img = ray_rb2image(self);

  if (rb_respond_to(arg, RAY_METH("read"))) {
    arg = rb_funcall(arg, RAY_METH("read"), 0);
    if (!say_image_load_from_memory(img, RSTRING_LEN(arg),
                                    StringValuePtr(arg))) {
      rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
    }
  }
  else if (rb_respond_to(arg, RAY_METH("to_str"))) {
    if (!say_image_load_file(img, StringValuePtr(arg))) {
      rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
    }
  }
  else {
    say_vector2 size = ray_convert_to_vector2(arg);
    if (!say_image_create_with_size(img, size.x, size.y))
      rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
  }

  return self;
}

Instance Method Details

#[](x, y) ⇒ Color

Reads the color of a pixel

Parameters:

  • x (Integer)

    X position of the pixel

  • y (Integer)

    Y position of the pixel

Returns:

  • (Color)

    Color of the pixel



178
179
180
181
182
183
184
185
186
187
188
# File 'ext/image.c', line 178

static
VALUE ray_image_get(VALUE self, VALUE rb_x, VALUE rb_y) {
  say_image *img = ray_rb2image(self);
  size_t x = NUM2ULONG(rb_x), y = NUM2ULONG(rb_y);

  if (x >= say_image_get_width(img) ||
      y >= say_image_get_height(img))
    return Qnil;

  return ray_col2rb(say_image_get(img, x, y));
}

#[]=(x, y, color) ⇒ Object

Changes the color of a pixel

Parameters:

  • x (Integer)

    X position of the pixel

  • y (Integer)

    Y position of the pixel

  • color (Color)

    New color of the pixel



199
200
201
202
203
204
205
206
207
208
209
210
# File 'ext/image.c', line 199

static
VALUE ray_image_set(VALUE self, VALUE rb_x, VALUE rb_y, VALUE color) {
  rb_check_frozen(self);

  say_image *img = ray_rb2image(self);
  size_t x = NUM2ULONG(rb_x), y = NUM2ULONG(rb_y);

  ray_image_assert_pos(img, x, y);

  say_image_set(img, x, y, ray_rb2col(color));
  return color;
}

#bindObject

Binds the texture, which will be used as GL_TEXTURE_2D when drawing with OpenGL

This is equivalent to calling #bind_to with unit set to 0.



236
237
238
239
# File 'ext/image.c', line 236

VALUE ray_image_bind(VALUE self) {
  say_image_bind(ray_rb2image(self));
  return self;
}

#bind_to(unit) ⇒ Object

Binds the texture to a given unit (0 <= unit < 32)

Parameters:

  • unit (Integer)

    Texture unit



246
247
248
249
250
251
252
253
254
# File 'ext/image.c', line 246

VALUE ray_image_bind_to(VALUE self, VALUE unit) {
  int c_unit = NUM2INT(unit);
  if (c_unit >= 32 || c_unit < 0)
    rb_raise(rb_eRangeError, "texture unit %d out of bounds", c_unit);

  say_image_bind_to(ray_rb2image(self), c_unit);

  return self;
}

#each {|pixel| ... } ⇒ Object

Iterates over all the pixels of an image

Iteration is done over each pixel from a line from left to right, and each line from top to bottom.

Yields:

  • (pixel)

Yield Parameters:



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/ray/image.rb', line 18

def each
  return Enumerator.new(self, :each) unless block_given?

  (0...h).each do |y|
    (0...w).each do |x|
      yield self[x, y]
    end
  end

  self
end

#each_with_pos {|pixel, x, y| ... } ⇒ Object

Yields all the pixels and their positions

Yields:

  • (pixel, x, y)

Yield Parameters:

  • pixel (Ray::Color)

    Color of the pixel

  • x (Integer)

    X position of the pixel

  • y (Integer)

    Y position of the pixel



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/ray/image.rb', line 36

def each_with_pos
  return Enumerator.new(self, :each_with_pos) unless block_given?

  (0...h).each do |y|
    (0...w).each do |x|
      yield self[x, y], x, y
    end
  end

  self
end

#heightInteger Also known as: h

Returns Height of the image in pixels.

Returns:

  • (Integer)

    Height of the image in pixels



146
147
148
149
# File 'ext/image.c', line 146

static
VALUE ray_image_height(VALUE self) {
  return INT2FIX(say_image_get_height(ray_rb2image(self)));
}

#initialize_copy(other) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
# File 'ext/image.c', line 67

static
VALUE ray_image_init_copy(VALUE self, VALUE other) {
  say_image *orig = ray_rb2image(other);

  say_image_load_flipped_raw(ray_rb2image(self),
                             say_image_get_width(orig),
                             say_image_get_height(orig),
                             say_image_get_buffer(orig));

  return self;
}

#inspectObject



109
110
111
# File 'lib/ray/image.rb', line 109

def inspect
  "#<#{self.class} size=#{size}>"
end

#map {|pixel| ... } ⇒ Ray::Image

Creates a new image using a block

Yields:

  • (pixel)

Yield Parameters:

Yield Returns:

Returns:

  • (Ray::Image)

    New image created according to a block



92
93
94
# File 'lib/ray/image.rb', line 92

def map(&block)
  dup.map!(&block)
end

#map! {|pixel| ... } ⇒ Object

Modifies each pixel of the image in-place

Yields:

  • (pixel)

Yield Parameters:

Yield Returns:



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ray/image.rb', line 54

def map!
  return Enumerator.new(self, :map!) unless block_given?

  (0...h).each do |y|
    (0...w).each do |x|
      self[x, y] = yield self[x, y]
    end
  end

  self
end

#map_with_pos {|pixel, x, y| ... } ⇒ Ray::Image

Creates a new image using a block, passing the position of each point to it

Yields:

  • (pixel, x, y)

Yield Parameters:

  • pixel (Ray::Color)

    Color of the pixel

  • x (Integer)

    X position of the pixel

  • y (Integer)

    Y position of the pixel

Returns:

  • (Ray::Image)

    New image created according to a block



103
104
105
# File 'lib/ray/image.rb', line 103

def map_with_pos(&block)
  dup.map_with_pos!(&block)
end

#map_with_pos! {|pixel, x, y| ... } ⇒ Object

Modifies each pixel of the image in-place, passing their position to the block

Yields:

  • (pixel, x, y)

Yield Parameters:

  • pixel (Ray::Color)

    Color of the pixel

  • x (Integer)

    X position of the pixel

  • y (Integer)

    Y position of the pixel



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ray/image.rb', line 73

def map_with_pos!
  return Enumerator.new(self, :map_with_pos!) unless block_given?

  (0...h).each do |y|
    (0...w).each do |x|
      self[x, y] = yield self[x, y], x, y
    end
  end

  self
end

#pretty_print(q) ⇒ Object



113
114
115
# File 'lib/ray/image.rb', line 113

def pretty_print(q)
  pretty_print_attributes q, ["size", "smooth?"]
end

#sizeRay::Vector2

Returns Size of the image in pixels.

Returns:



152
153
154
155
# File 'ext/image.c', line 152

static
VALUE ray_image_size(VALUE self) {
  return ray_vector2_to_rb(say_image_get_size(ray_rb2image(self)));
}

#smooth=(val) ⇒ Object

Enables or disables smoothing

When smoothing is enabled, the color of interpolated pixels is chosen by taking the average of the four colors that are the nearest to each of them (linear interpolation). When it is not enabled, the color of the nearest point is simply used.

Smoothing is disabled by default.

Parameters:

  • val (Boolean)

    True to enable smoothing



283
284
285
286
287
# File 'ext/image.c', line 283

VALUE ray_image_set_smooth(VALUE self, VALUE val) {
  rb_check_frozen(self);
  say_image_set_smooth(ray_rb2image(self), RTEST(val));
  return val;
}

#smooth?Boolean

Returns:

  • (Boolean)

See Also:



266
267
268
# File 'ext/image.c', line 266

VALUE ray_image_is_smooth(VALUE self) {
  return say_image_is_smooth(ray_rb2image(self)) ? Qtrue : Qfalse;
}

#tex_rect(rect) ⇒ Rect

Converts a rect of pixel coordinates to a rect of texture coordinates

Texture coordinates can be useful when manually generating vertices that need to be textured.

The returned rect is setup so that (x,y) is the top left corner of the image. The height of the rect may thus be negative.

Parameters:

  • rect (Rect)

    Rect in pixel coordinates

Returns:

  • (Rect)

    Rect in texture coordinates



225
226
227
228
# File 'ext/image.c', line 225

VALUE ray_image_tex_rect(VALUE self, VALUE rect) {
  return ray_rect2rb(say_image_get_tex_rect(ray_rb2image(self),
                                            ray_convert_to_rect(rect)));
}

#textureInteger

Returns Identifer of the image’s texture.

Returns:

  • (Integer)

    Identifer of the image’s texture



259
260
261
# File 'ext/image.c', line 259

VALUE ray_image_texture(VALUE self) {
  return ULONG2NUM(say_image_get_texture(ray_rb2image(self)));
}

#turtle { ... } ⇒ Ray::Turtle

Creates a turtle operating on the receiver

If a block is passed, it is instance-evaluated (self becoming the turtle) and the receiver gets updated automatically.

Yields:

  • Optionally perform drawing in the block

Returns:

See Also:



207
208
209
# File 'lib/ray/turtle.rb', line 207

def turtle(&block)
  Ray::ImageTarget.new(self).turtle(&block)
end

#widthInteger Also known as: w

Returns Width of the image in pixels.

Returns:

  • (Integer)

    Width of the image in pixels



140
141
142
143
# File 'ext/image.c', line 140

static
VALUE ray_image_width(VALUE self) {
  return INT2FIX(say_image_get_width(ray_rb2image(self)));
}

#write(filename) ⇒ Object

Saves the image in any format supported by Ray

This will try to guess the format based on the filename extension (regardless of the case). If Ray can’t guess the filename, the image will be saved anyway using TGA.



130
131
132
133
134
135
136
137
# File 'ext/image.c', line 130

static
VALUE ray_image_write(VALUE self, VALUE filename) {
  if (!say_image_write(ray_rb2image(self), StringValuePtr(filename))) {
    rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
  }

  return self;
}

#write_bmp(filename) ⇒ Object

Saves the image as a BMP

Notice BMP output ignores alpha channel. Use PNG or TGA output when possible.



86
87
88
89
90
91
92
93
# File 'ext/image.c', line 86

static
VALUE ray_image_write_bmp(VALUE self, VALUE filename) {
  if (!say_image_write_bmp(ray_rb2image(self), StringValuePtr(filename))) {
    rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
  }

  return self;
}

#write_png(filename) ⇒ Object

Saves the image as a PNG

Raises:

  • (RuntimeError)

    This method will not work on Windows.



100
101
102
103
104
105
106
107
# File 'ext/image.c', line 100

static
VALUE ray_image_write_png(VALUE self, VALUE filename) {
  if (!say_image_write_png(ray_rb2image(self), StringValuePtr(filename))) {
    rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
  }

  return self;
}

#write_tga(filename) ⇒ Object

Saves the image as a TGA



113
114
115
116
117
118
119
120
# File 'ext/image.c', line 113

static
VALUE ray_image_write_tga(VALUE self, VALUE filename) {
  if (!say_image_write_tga(ray_rb2image(self), StringValuePtr(filename))) {
    rb_raise(rb_eRuntimeError, "%s", say_error_get_last());
  }

  return self;
}