Class: Pura::Webp::Image

Inherits:
Object
  • Object
show all
Defined in:
lib/pura/webp/image.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width, height, pixels) ⇒ Image

Returns a new instance of Image.

Raises:

  • (ArgumentError)


8
9
10
11
12
13
14
15
16
# File 'lib/pura/webp/image.rb', line 8

def initialize(width, height, pixels)
  @width = width
  @height = height
  @pixels = pixels.b
  expected = width * height * 3
  return if @pixels.bytesize == expected

  raise ArgumentError, "pixel data size #{@pixels.bytesize} != expected #{expected} (#{width}x#{height}x3)"
end

Instance Attribute Details

#heightObject (readonly)

Returns the value of attribute height.



6
7
8
# File 'lib/pura/webp/image.rb', line 6

def height
  @height
end

#pixelsObject (readonly)

Returns the value of attribute pixels.



6
7
8
# File 'lib/pura/webp/image.rb', line 6

def pixels
  @pixels
end

#widthObject (readonly)

Returns the value of attribute width.



6
7
8
# File 'lib/pura/webp/image.rb', line 6

def width
  @width
end

Instance Method Details

#crop(x, y, w, h) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/pura/webp/image.rb', line 83

def crop(x, y, w, h)
  out = String.new(encoding: Encoding::BINARY, capacity: w * h * 3)
  h.times do |row|
    src_offset = (((y + row) * @width) + x) * 3
    out << @pixels.byteslice(src_offset, w * 3)
  end
  Image.new(w, h, out)
end

#pixel_at(x, y) ⇒ Object

Raises:

  • (IndexError)


30
31
32
33
34
35
# File 'lib/pura/webp/image.rb', line 30

def pixel_at(x, y)
  raise IndexError, "coordinates out of bounds" if x.negative? || x >= @width || y.negative? || y >= @height

  offset = ((y * @width) + x) * 3
  [@pixels.getbyte(offset), @pixels.getbyte(offset + 1), @pixels.getbyte(offset + 2)]
end

#resize(new_width, new_height, interpolation: :bilinear) ⇒ Object

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
49
50
51
# File 'lib/pura/webp/image.rb', line 42

def resize(new_width, new_height, interpolation: :bilinear)
  raise ArgumentError, "width must be positive" unless new_width.positive?
  raise ArgumentError, "height must be positive" unless new_height.positive?

  if interpolation == :nearest
    resize_nearest(new_width, new_height)
  else
    resize_bilinear(new_width, new_height)
  end
end

#resize_fill(fill_width, fill_height, interpolation: :bilinear) ⇒ Object

Raises:

  • (ArgumentError)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/pura/webp/image.rb', line 66

def resize_fill(fill_width, fill_height, interpolation: :bilinear)
  raise ArgumentError, "width must be positive" unless fill_width.positive?
  raise ArgumentError, "height must be positive" unless fill_height.positive?

  scale = [fill_width.to_f / @width, fill_height.to_f / @height].max
  scaled_w = (@width * scale).round
  scaled_h = (@height * scale).round
  scaled_w = 1 if scaled_w < 1
  scaled_h = 1 if scaled_h < 1

  scaled = resize(scaled_w, scaled_h, interpolation: interpolation)

  crop_x = (scaled_w - fill_width) / 2
  crop_y = (scaled_h - fill_height) / 2
  scaled.crop(crop_x, crop_y, fill_width, fill_height)
end

#resize_fit(max_width, max_height, interpolation: :bilinear) ⇒ Object

Raises:

  • (ArgumentError)


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

def resize_fit(max_width, max_height, interpolation: :bilinear)
  raise ArgumentError, "max_width must be positive" unless max_width.positive?
  raise ArgumentError, "max_height must be positive" unless max_height.positive?

  scale = [max_width.to_f / @width, max_height.to_f / @height].min
  scale = [scale, 1.0].min
  new_width = (@width * scale).round
  new_height = (@height * scale).round
  new_width = 1 if new_width < 1
  new_height = 1 if new_height < 1
  resize(new_width, new_height, interpolation: interpolation)
end

#to_ppmObject



37
38
39
40
# File 'lib/pura/webp/image.rb', line 37

def to_ppm
  header = "P6\n#{@width} #{@height}\n255\n"
  header.b + @pixels
end

#to_rgb_arrayObject



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

def to_rgb_array
  result = Array.new(width * height)
  i = 0
  offset = 0
  while offset < @pixels.bytesize
    result[i] = [@pixels.getbyte(offset), @pixels.getbyte(offset + 1), @pixels.getbyte(offset + 2)]
    i += 1
    offset += 3
  end
  result
end