class SparkCanvas
Attributes
color[RW]
height[R]
width[R]
Public Class Methods
new(width,height,base_color=[0xFF,0xFF,0xFF])
click to toggle source
# 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
Public Instance Methods
blend(c1, c2)
click to toggle source
alpha blends two colors, using the alpha given by c2
# 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)
click to toggle source
# 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)
click to toggle source
calculate perceptive grayscale value
# 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)
click to toggle source
calculate a new alpha given a 0-0xFF intensity
# 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)
click to toggle source
draw an antialiased line google for “wu antialiasing”
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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_ascii()
click to toggle source
# 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_png()
click to toggle source
# 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