Skip to content

Instantly share code, notes, and snippets.

@mikrostew
Created July 23, 2014 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikrostew/4e411930bf47f936b0ad to your computer and use it in GitHub Desktop.
Save mikrostew/4e411930bf47f936b0ad to your computer and use it in GitHub Desktop.
Displays images saved in PBM/PGM/PPM ascii formats
#!/usr/bin/ruby
require 'tk'
IMG_BORDER = 10
MIN_IMG_SIZE = 100
# use the filename entered on the command line, else prompt
def get_filename
return ARGV[0] if ARGV.length > 0
print "Enter file name: "
gets.chomp
end
filename = get_filename()
# read entire file, strip comments, and split into array
file_data = File.read(filename).gsub(/#[^\n]*$/,'').split(/\s+/)
format = file_data.shift
img_width, img_height = file_data.shift(2).map { |x| x.to_i }
# P1 format doesn't necessarily have whitespace between pixel values
if format == "P1" && file_data[0].length > 1
file_data = file_data.map { |x| x.chars.to_a }.flatten
end
# max_value is 1 for P1, and defined in the file for P2 and P3
max_value = ["P2", "P3"].include?(format) ? file_data.shift.to_i : 1
abort "Error: max value > 255" if max_value > 255
img_data = []
pixel_width = (format == "P3") ? img_width*3 : img_width
file_data.each_slice(pixel_width) do |line|
abort "Not enough pixel data" if line.length < pixel_width
line_data = []
case format
when "P1"
# (invert the values because otherwise 1 => FFFFFF which is white, not black)
line_data = line.map { |c| c = c=='0'?'1':'0'; [c, c, c] }
when "P2"
line_data = line.map { |i| [i, i, i] }
when "P3"
line_data = line.each_slice(3).to_a
else
abort "Unknown image format '#{format}' (expected: 'P1', 'P2', or 'P3')"
end
img_data << line_data.map do |triplet|
"##{triplet.map { |i| "%02X" % (i.to_i * 255 / max_value) }.join}"
end
end
# render the image in a window (ensure minimum window size)
win_width = img_width > MIN_IMG_SIZE ? img_width + IMG_BORDER*2 : MIN_IMG_SIZE + IMG_BORDER*2
win_height = img_height + IMG_BORDER*2
root = TkRoot.new(:title => filename, :width => win_width, :height => win_height)
image = TkPhotoImage.new(:width => img_width, :height => img_height).put(img_data, 0, 0)
label = TkLabel.new(root, :image => image)
label.place('height' => img_height, 'width' => img_width, 'x' => IMG_BORDER, 'y' => IMG_BORDER)
Tk.mainloop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment