class ImageWriter

Constants

HORIZ_DPI_CODE

Send Esc + this letter to change horizontal DPI

LINE_FEEDS

Send x1F then this letter to send N line feeds

Public Class Methods

new(argv) click to toggle source
# File bin/imagewriter, line 17
def initialize(argv)
  parse_argv!(argv.clone)

  @img = ChunkyPNG::Image.from_file(@filename)
  STDERR.puts "#{@filename}: height #{@img.height}, width #{@img.width}"

  printable_width = @hdpi * 8
  if @img.width > printable_width
    STDERR.puts "Warning: image exceeds printable width of #{printable_width} pixels; printout will be clipped"
  end
end

Public Instance Methods

b1(x, y) click to toggle source

Returns data byte for first-pass lines

# File bin/imagewriter, line 164
def b1(x, y)
  0 +
    0b00000001 * get(x, y) +
    0b00000010 * get(x, y+2) +
    0b00000100 * get(x, y+4) +
    0b00001000 * get(x, y+6) +
    0b00010000 * get(x, y+8) +
    0b00100000 * get(x, y+10) +
    0b01000000 * get(x, y+12) +
    0b10000000 * get(x, y+14)
end
b2(x, y) click to toggle source

Returns data byte for second-pass lines

# File bin/imagewriter, line 177
def b2(x, y)
  0 +
    0b00000001 * get(x, y+1) +
    0b00000010 * get(x, y+3) +
    0b00000100 * get(x, y+5) +
    0b00001000 * get(x, y+7) +
    0b00010000 * get(x, y+9) +
    0b00100000 * get(x, y+11) +
    0b01000000 * get(x, y+13) +
    0b10000000 * get(x, y+15)
end
get(x, y) click to toggle source

Returns 1 for black pixels that exist, 0 otherwise

# File bin/imagewriter, line 190
def get(x, y)
  x = @img[x, y] & 0xffffff00 # strip alpha channel
  return 0 if x > 0
  1
rescue
  0
end
init_printer!() click to toggle source
# File bin/imagewriter, line 198
def init_printer!
  print "\eT01" # set line feed to 1/144 inch
  printf "\e%s", HORIZ_DPI_CODE[@hdpi]
end
parse_argv!(argv) click to toggle source
# File bin/imagewriter, line 102
  def parse_argv!(argv)
    options = {
      hdpi: 144,
      quality: 1,
      sleep: 0.75
    }

    help = nil
    OptionParser.new do |parser|
      parser.banner = <<-EOT
Usage: imagewriter [options] filename.png
Vertical resolution is 144 dpi; horizontal resolution is adjustable.
Max printable width is 8 inches, or 8 * horizontal DPI pixels.
Options:
      EOT

      dpis = HORIZ_DPI_CODE.keys.join(", ")
      parser.on('-H', '--horizontal DPI', Integer, "Horizontal DPI. One of: #{dpis}; default #{options[:hdpi]}") do |n|
        if HORIZ_DPI_CODE[n]
          options[:hdpi] = n
        else
          STDERR.puts "Bad horizontal DPI setting #{n} (must be one of: #{dpis})\n"
          STDERR.puts parser.to_s
          exit 1
        end
      end

      parser.on("-q", "--quality QUALITY", Integer, "Print quality. 1 (fastest) to 7 (best); default #{options[:quality]}") do |n|
        if n > 0 && n < 8
          options[:quality] = n
        else
          STDERR.puts "Bad quality setting #{n} (must be 1-7)"
          STDERR.puts parser
          exit 1
        end
      end

      parser.on("-s", "--sleep SECONDS", Float, "Sleep this many seconds between passes. Default #{options[:sleep]}") do |n|
        options[:sleep] = n
      end

      parser.on("-h", "--help", "Print this help message to STDERR") do
        STDERR.puts parser
        exit
      end

      help = parser.to_s
    end.parse!(argv)

    @hdpi = options[:hdpi]
    @quality = options[:quality]
    @sleep = options[:sleep]

    @filename = argv.shift
    if !@filename
      STDERR.puts "Missing filename\n"
      STDERR.puts help
      exit 1
    end
  end
print!() click to toggle source

Prints an image at double vertical resolution (144 dpi) by writing interleaved rows in a back-and-forth “double pass”.