Class: RawImage::Image

Inherits:
Object
  • Object
show all
Includes:
GuiGeo, RawImage, Colors
Defined in:
lib/raw_image/image.rb

Constant Summary

Constants included from RawImage

VERSION

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Colors

#black, #gray, #transparent, #white

Methods included from RawImage

#color, color_formats, #image

Constructor Details

#initialize(options = {}) ⇒ Image

:format => symbol :size => point :data => string :line_byte_size => integer or nil :color => Color (clear-to-color if data is nil)

Raises:

  • (ArgumentError)


26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/raw_image/image.rb', line 26

def initialize(options={})
  @format = options[:format] || :rgba8
  raise ArgumentError.new("unsupported format: #{format.inspect}") unless RawImage.color_formats[format]

  @size = options[:size]
  raise ArgumentError.new("size#{size} must be at least (1,1)") unless size > point

  @line_byte_size = options[:line_byte_size] || minimum_line_byte_size
  raise ArgumentError.new("line_byte_size must be at least #{minimum_line_byte_size} for the given format #{format.inspect} and size #{size}") unless line_byte_size >= minimum_line_byte_size

  @data = options[:data] || new_data(options[:color])
  raise ArgumentError.new("expecting data to be #{byte_size} bytes (was #{data.length})") unless data.length == byte_size
end

Instance Attribute Details

#dataObject (readonly)

raw image data as a binary string



10
11
12
# File 'lib/raw_image/image.rb', line 10

def data
  @data
end

#formatObject (readonly)

pixel format of iamge



16
17
18
# File 'lib/raw_image/image.rb', line 16

def format
  @format
end

#line_byte_sizeObject (readonly)

length of each line in bytes



19
20
21
# File 'lib/raw_image/image.rb', line 19

def line_byte_size
  @line_byte_size
end

#sizeObject (readonly)

width & height of the image



13
14
15
# File 'lib/raw_image/image.rb', line 13

def size
  @size
end

Instance Method Details

#areaObject

the rectangle defining the area of the image



50
# File 'lib/raw_image/image.rb', line 50

def area; rect size; end

#byte_offset(loc) ⇒ Object

get the byte-offset into data of a given pixel location



53
# File 'lib/raw_image/image.rb', line 53

def byte_offset(loc) loc.y * line_byte_size + loc.x * pixel_byte_size; end

#byte_sizeObject

total byte-size of the string (should always == data.length)



41
# File 'lib/raw_image/image.rb', line 41

def byte_size; size.y * line_byte_size; end

#pixel_byte_sizeObject

bytes per pixel



47
# File 'lib/raw_image/image.rb', line 47

def pixel_byte_size; RawImage.color_formats[format][:byte_size]; end

#pixel_sizeObject

number of pixels in image



44
# File 'lib/raw_image/image.rb', line 44

def pixel_size; size.x * size.y; end

#replace_image(loc, image, source_sub_area = nil) ⇒ Object

replace the pixels of the given sub_area (GuiGeo::Rectangle) with the pixels of the given image (Image) optional: specify a sub-area of the source image to copy

Raises:

  • (ArgumentError)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/raw_image/image.rb', line 91

def replace_image(loc, image, source_sub_area = nil)
  raise ArgumentError.new unless format == image.format
  loc -= source_sub_area.loc if source_sub_area
  source_sub_area = (area - loc) | image.area | source_sub_area
  target_sub_area = source_sub_area + loc
  return unless target_sub_area.present?

  data = @data
  w = source_sub_area.w
  l = source_sub_area.loc
  each_line(target_sub_area) do |range|
    data[range] = image.sub_horizontal_line(l, w)
    l.y += 1
  end
end

#replace_rect(sub_area, color) ⇒ Object

replace the pixels of the given sub_area (GuiGeo::Rectangle) with the specified Image::Color



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/raw_image/image.rb', line 77

def replace_rect(sub_area, color)
  sub_area = area | sub_area
  return unless sub_area.present?

  replace_line = color.to_bytes(format) * sub_area.w

  data = @data
  each_line(sub_area) do |range|
    data[range] = replace_line
  end
end

#sub_horizontal_line(start, length) ⇒ Object

return the byte of a single horizontal sub-line of data (start is a GuiGeo::Point)



57
58
59
60
# File 'lib/raw_image/image.rb', line 57

def sub_horizontal_line(start, length)
  offset = byte_offset start
  data[offset .. (offset + (length*pixel_byte_size)-1)]
end

#subimage(sub_area) ⇒ Object

return a new image with the pixels from the specified sub_area (GuiGeo::Rectangle)



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/raw_image/image.rb', line 63

def subimage(sub_area)
  sub_area = area | sub_area

  byte_width_minus_one = sub_area.w * pixel_byte_size - 1
  stride = line_byte_size
  offset = byte_offset(sub_area.loc) - stride
  data = @data
  Image.new :size => sub_area.size, :format => format, :data => (sub_area.h.times.collect do
    offset += stride
    data[offset .. (offset + byte_width_minus_one)]
  end).join
end