Parent

Class Index [+]

Quicksearch

PNG::Canvas

A canvas used for drawing images. Origin is 0, 0 in the bottom left corner.

Attributes

height[R]

Height of the canvas

width[R]

Width of the canvas

data[R]

Raw data

Public Class Methods

new(width, height, background = Color::Background) click to toggle source
     # File lib/png.rb, line 420
420:     def initialize width, height, background = Color::Background
421:       @width = width
422:       @height = height
423:       @data = Array.new(@height) { |x| Array.new(@width, background) }
424:     end

Public Instance Methods

[](x, y) click to toggle source

Retrieves the color of the pixel at (x, y).

     # File lib/png.rb, line 429
429:     def [] x, y
430:       raise "bad x value #{x} >= #{@width}" if x >= @width
431:       raise "bad y value #{y} >= #{@height}" if y >= @height
432:       @data[@height-y-1][x]
433:     end
[]=(x, y, color) click to toggle source

Sets the color of the pixel at (x, y) to color.

     # File lib/png.rb, line 438
438:     def []= x, y, color
439:       raise "bad x value #{x} >= #{@width}" if x >= @width
440:       raise "bad y value #{y} >= #{@height}"  if y >= @height
441:       raise "bad color #{color.inspect}" unless color.kind_of? PNG::Color
442:       @data[@height-y-1][x] = color
443:     end
annotate(string, x, y, font = PNG::Font.default, align = :left, style = :overwrite) click to toggle source

Write a string at [x, y] with font, optionally specifying a font, an alignment of :left, :center, or :right and the style to draw the annotation (see composite).

  require 'png/font'
    # File lib/png/font.rb, line 53
53:   def annotate(string, x, y,
54:                font = PNG::Font.default, align = :left, style = :overwrite)
55:     case align
56:     when :left then
57:       # do nothing
58:     when :center then
59:       x -= string.length * font.width / 2
60:     when :right then
61:       x -= string.length * font.width
62:     else
63:       raise ArgumentError, "Unknown align: #{align.inspect}"
64:     end
65: 
66:     x_offset, width = 0, font.width
67: 
68:     string.split(//).each do |char|
69:       self.composite font[char], x + x_offset, y
70:       x_offset += width
71:     end
72:   end
composite(canvas, x, y, style = :overwrite) click to toggle source

Composites another canvas onto self at the given (bottom left) coordinates.

     # File lib/png.rb, line 448
448:     def composite canvas, x, y, style = :overwrite
449:       canvas.each do |x1, y1, color|
450:         case style
451:         when :overwrite then
452:           self[x+x1, y+y1] = color
453:         when :add, :underlay then
454:           self[x+x1, y+y1] = self[x+x1, y+y1] | color
455:         when :overlay then
456:           self[x+x1, y+y1] = color | self[x+x1, y+y1]
457:         when :blend then
458:           self.point x+x1, y+y1, color
459:         else
460:           raise "unknown style for composite: #{style.inspect}"
461:         end
462:       end
463:     end
each() click to toggle source

Iterates over the canvas yielding x, y, and color.

     # File lib/png.rb, line 468
468:     def each
469:       data.reverse.each_with_index do |row, y|
470:         row.each_with_index do |color, x|
471:           yield x, y, color
472:         end
473:       end
474:     end
extract(x0, y0, x1, y1) click to toggle source

Create a new canvas copying a region of the current canvas

     # File lib/png.rb, line 479
479:     def extract x0, y0, x1, y1
480:       canvas = Canvas.new(x1-x0+1, y1-y0+1)
481: 
482:       (x0..x1).each_with_index do |x2, x3|
483:         (y0..y1).each_with_index do |y2, y3|
484:           canvas[x3, y3] = self[x2, y2]
485:         end
486:       end
487: 
488:       canvas
489:     end
line(x0, y0, x1, y1, color) click to toggle source

Draws a line using Xiaolin Wu’s antialiasing technique.

en.wikipedia.org/wiki/Xiaolin_Wu's_line_algorithm

     # File lib/png.rb, line 507
507:     def line(x0, y0, x1, y1, color)
508:       y0, y1, x0, x1 = y1, y0, x1, x0 if y0 > y1
509:       dx = x1 - x0
510:       sx = dx < 0 ? 1 : 1
511:       dx *= sx
512:       dy = y1 - y0
513: 
514:       # 'easy' cases
515:       if dy == 0 then
516:         Range.new(*[x0,x1].sort).each do |x|
517:           point(x, y0, color)
518:         end
519:         return
520:       end
521: 
522:       if dx == 0 then
523:         (y0..y1).each do |y|
524:           point(x0, y, color)
525:         end
526:         return
527:       end
528: 
529:       if dx == dy then
530:         x0.step(x1, sx) do |x|
531:           point(x, y0, color)
532:           y0 += 1
533:         end
534:         return
535:       end
536: 
537:       # main loop
538:       point(x0, y0, color)
539:       e_acc = 0
540:       if dy > dx then # vertical displacement
541:         e = (dx << 16) / dy
542:         (y0...y1-1).each do |i|
543:           e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF
544:           x0 = x0 + sx if (e_acc <= e_acc_temp)
545:           w = 0xFF-(e_acc >> 8)
546:           point(x0, y0, color.intensity(w))
547:           y0 = y0 + 1
548:           point(x0 + sx, y0, color.intensity(0xFF-w))
549:         end
550:         point(x1, y1, color)
551:         return
552:       end
553: 
554:       # horizontal displacement
555:       e = (dy << 16) / dx
556:       (dx - 1).downto(0) do |i|
557:         e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF
558:         y0 += 1 if (e_acc <= e_acc_temp)
559:         w = 0xFF-(e_acc >> 8)
560:         point(x0, y0, color.intensity(w))
561:         x0 += sx
562:         point(x0, y0 + 1, color.intensity(0xFF-w))
563:       end
564:       point(x1, y1, color)
565:     end
point(x, y, color) click to toggle source

Blends color onto the color at point (x, y).

     # File lib/png.rb, line 498
498:     def point(x, y, color)
499:       self[x,y] = self[x,y].blend(color)
500:     end
to_s() click to toggle source

Returns an ASCII representation of this image

     # File lib/png.rb, line 570
570:     def to_s
571:       image = []
572:       scale = (@width / 39) + 1
573: 
574:       @data.each_with_index do |row, x|
575:         next if x % scale != 0
576:         row.each_with_index do |color, y|
577:           next if y % scale != 0
578:           image << color.to_ascii
579:         end
580:         image << "\n"
581:       end
582: 
583:       return image.join
584:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.