Class: SparkCanvas

Inherits:
Object
  • Object
show all
Defined in:
lib/spark_pr/spark_canvas.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width, height, base_color = [0xFF,0xFF,0xFF]) ⇒ SparkCanvas

Returns a new instance of SparkCanvas.



16
17
18
19
20
21
22
# File 'lib/spark_pr/spark_canvas.rb', line 16

def initialize(width,height,base_color=[0xFF,0xFF,0xFF])
  @canvas = []
  @height = height
  @width = width
  height.times{ @canvas << [base_color]*width }
  @color = [0,0,0,0xFF] #RGBA
end

Instance Attribute Details

#colorObject

Returns the value of attribute color.



13
14
15
# File 'lib/spark_pr/spark_canvas.rb', line 13

def color
  @color
end

#heightObject (readonly)

Returns the value of attribute height.



14
15
16
# File 'lib/spark_pr/spark_canvas.rb', line 14

def height
  @height
end

#widthObject (readonly)

Returns the value of attribute width.



14
15
16
# File 'lib/spark_pr/spark_canvas.rb', line 14

def width
  @width
end

Instance Method Details

#blend(c1, c2) ⇒ Object

alpha blends two colors, using the alpha given by c2



25
26
27
# File 'lib/spark_pr/spark_canvas.rb', line 25

def blend(c1, c2)
  (0..2).map{ |i| (c1[i]*(0xFF-c2[3]) + c2[i]*c2[3]) >> 8 }
end

#build_png_chunk(type, data) ⇒ Object



106
107
108
109
# File 'lib/spark_pr/spark_canvas.rb', line 106

def build_png_chunk(type,data)
  to_check = type + data
  [data.length].pack("N") + to_check + [Zlib.crc32(to_check)].pack("N")
end

#grayscale(c) ⇒ Object

calculate perceptive grayscale value



35
36
37
# File 'lib/spark_pr/spark_canvas.rb', line 35

def grayscale(c)
  (c[0]*0.3 + c[1]*0.59 + c[2]*0.11).to_i
end

#intensity(c, i) ⇒ Object

calculate a new alpha given a 0-0xFF intensity



30
31
32
# File 'lib/spark_pr/spark_canvas.rb', line 30

def intensity(c,i)
  [c[0],c[1],c[2],(c[3]*i) >> 8]
end

#line(x0, y0, x1, y1) ⇒ Object

draw an antialiased line google for “wu antialiasing”



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
# File 'lib/spark_pr/spark_canvas.rb', line 53

def line(x0, y0, x1, y1)
  # clean params
  x0, y0, x1, y1 = x0.to_i, y0.to_i, x1.to_i, y1.to_i
  y0, y1, x0, x1 = y1, y0, x1, x0 if y0>y1
  sx = (dx = x1-x0) < 0 ? -1 : 1 ; dx *= sx ; dy = y1-y0

  # special cases
  x0.step(x1,sx) { |x| point x, y0 } and return if dy.zero?
  y0.upto(y1)    { |y| point x0, y } and return if dx.zero?
  x0.step(x1,sx) { |x| point x, y0; y0 += 1 } and return if dx==dy

  # main loops
  point x0, y0

  e_acc = 0
  if dy > dx
    e = (dx << 16) / dy
    y0.upto(y1-1) do
      e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF
      x0 += sx if (e_acc <= e_acc_temp)
      point x0, (y0 += 1), intensity(@color,(w=0xFF-(e_acc >> 8)))
      point x0+sx, y0, intensity(@color,(0xFF-w))
    end
    point x1, y1
    return
  end

  e = (dy << 16) / dx
  x0.step(x1-sx,sx) do
    e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF
    y0 += 1 if (e_acc <= e_acc_temp)
    point (x0 += sx), y0, intensity(@color,(w=0xFF-(e_acc >> 8)))
    point x0, y0+1, intensity(@color,(0xFF-w))
  end
  point x1, y1
end

#point(x, y, color = nil) ⇒ Object



39
40
41
42
# File 'lib/spark_pr/spark_canvas.rb', line 39

def point(x,y,color = nil)
  return if x<0 or y<0 or x>@width-1 or y>@height-1
  @canvas[y][x] = blend(@canvas[y][x], color || @color)
end

#polyline(arr) ⇒ Object



90
91
92
# File 'lib/spark_pr/spark_canvas.rb', line 90

def polyline(arr)
  (0...arr.size-1).each{ |i| line(arr[i][0], arr[i][1], arr[i+1][0], arr[i+1][1]) }
end

#rectangle(x0, y0, x1, y1) ⇒ Object



44
45
46
47
48
49
# File 'lib/spark_pr/spark_canvas.rb', line 44

def rectangle(x0, y0, x1, y1)
  x0, y0, x1, y1 = x0.to_i, y0.to_i, x1.to_i, y1.to_i
  x0, x1 = x1, x0 if x0 > x1
  y0, y1 = y1, y0 if y0 > y1
  x0.upto(x1) { |x| y0.upto(y1) { |y| point x, y } }
end

#to_asciiObject



111
112
113
114
# File 'lib/spark_pr/spark_canvas.rb', line 111

def to_ascii
  chr = %w(M O # + ; - .) << ' '
  @canvas.map{ |r| r.map { |pt| chr[grayscale(pt) >> 5] }.join << "\n" }.join
end

#to_pngObject



94
95
96
97
98
99
100
101
102
103
104
# File 'lib/spark_pr/spark_canvas.rb', line 94

def to_png
  header = [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
  raw_data = @canvas.map { |row| [0] + row }.flatten.pack("C*")
  ihdr_data = [@canvas.first.length,@canvas.length,8,2,0,0,0].pack("NNCCCCC")

  header +
    build_png_chunk("IHDR", ihdr_data) +
    build_png_chunk("tRNS", ([ 0xFF ]*6).pack("C6")) +
    build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data)) +
    build_png_chunk("IEND", "")
end