[QUIZ] Text Image (#50)

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

···

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

This week's Ruby Quiz is to create a tool that will allow you to preview an
image file at the command-line in pure text.

Your program will need to read in an image, in whatever format you want to
support, and respond with a text representation of the image that fits in the
terminal.

For example, given the image:

  http://rubyquiz.com/images/Ducky.png

Your program might respond with something like:

  ........--**####**::::::::::::........
  ......--##oooooo\\**::::::::..........
  ......**oo==oooo\\\\::::..............
  ....--\\oooooooo\\$$**::..............
  ....**&&$$oooo\\$$$$%%................
  ....**\\oooo\\<<<<$$##................
  ....!!<<<<<<<<<<\\\\##..........::::::
  ....::%%<<<<<<<<\\$$^^....::**++**....
  ....^^%%<<<<<<<<$$$$##**""==++++==****
  ....**oo<<<<<<$$<<<<\\oo==++++++==""""
  ..!!==oo<<<<<<<<$$$$oo====++++==oo####
  ^^====oo\\<<$$\\oooooo==++======oo****
  **++++====oooo====++++======oooo\\^^^^
  ++====++++========++======oooooo**....
  ""====++++==========oooooooooo##--....
  ""==================oooooooooo^^......
  !!oo==oo======oooooooooo\\##^^::......
  ..""oooooooooooooooo\\oo""^^..........
  ..::**====oooooooooo==**::............
  ....::^^**""""""""!!..--::............
  ....::^^**""""""""!!..--::............

Go for as much accuracy as you can possibly squeeze out of it.

Ahh, a half-toning algorithm.

···

On 10/7/05, Ruby Quiz <james@grayproductions.net> wrote:

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2. Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3. Enjoy!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

This week's Ruby Quiz is to create a tool that will allow you to preview an
image file at the command-line in pure text.

Your program will need to read in an image, in whatever format you want to
support, and respond with a text representation of the image that fits in the
terminal.

For example, given the image:

        http://rubyquiz.com/images/Ducky.png

Your program might respond with something like:

        ........--**####**::::::::::::........
        ......--##oooooo\\**::::::::..........
        ......**oo==oooo\\\\::::..............
        ....--\\oooooooo\\$$**::..............
        ....**&&$$oooo\\$$$$%%................
        ....**\\oooo\\<<<<$$##................
        ....!!<<<<<<<<<<\\\\##..........::::::
        ....::%%<<<<<<<<\\$$^^....::**++**....
        ....^^%%<<<<<<<<$$$$##**""==++++==****
        ....**oo<<<<<<$$<<<<\\oo==++++++==""""
        ..!!==oo<<<<<<<<$$$$oo====++++==oo####
        ^^====oo\\<<$$\\oooooo==++======oo****
        **++++====oooo====++++======oooo\\^^^^
        ++====++++========++======oooooo**....
        ""====++++==========oooooooooo##--....
        ""==================oooooooooo^^......
        !!oo==oo======oooooooooo\\##^^::......
        ..""oooooooooooooooo\\oo""^^..........
        ..::**====oooooooooo==**::............
        ....::^^**""""""""!!..--::............
        ....::^^**""""""""!!..--::............

Go for as much accuracy as you can possibly squeeze out of it.

--
Jim Freeze

Ruby Quiz wrote:

This week's Ruby Quiz is to create a tool that will allow you to preview an
image file at the command-line in pure text.

Your program will need to read in an image, in whatever format you want to
support, and respond with a text representation of the image that fits in the
terminal.

I never participate in these, but this one is tempting.

What about ANSI color? :wink:

Hal

Hi,

here is my attempt of solving this weeks quiz:

This solution uses the RMagick lib to read the image and
to find edges because trying to find apropiate letters for
halftoning is hard on all the different terminals.

I had another version without the generator/enumerator
stuff and it was a lot faster. But speed isn't an issue this
week and it's so much smoother than fiddling with indexes.

cheers

Simon

···

----------------------------------------------------------------
require 'RMagick'
require 'generator'
require 'enumerator'

puts "Usage: #{$0} <img> [size]" or exit if !ARGV[0]

img, size = Magick::ImageList.new(ARGV[0]), (ARGV[1]||40).to_f
factor = [size*1.5/img.rows, size/img.columns].min

img.resize!(img.columns*factor, 2*(img.rows*factor*0.75).round)
img = img.edge.despeckle.despeckle.normalize.threshold(50)

pixels = img.get_pixels(0, 0, img.columns, img.rows).map{|c| c.red.zero?}

pixels.to_enum(:each_slice, img.columns).each_slice(2) do |l|
   puts SyncEnumerator.new(*l).map{|p1, p2|
     [' ', "'", ".", ":"] [(p1 ? 0 : 1) + (p2 ? 0 : 2)]}.join('')
end
----------------------------------------------------------------

sample output:

          .:'''''''.
         .: :.
        .: :.
        : :
       :' ':
      .: :
      : .':. ::
     :'.' : .. ':
     : :..' :' ': :
     :. ' : .: :
     ': '::'':.. ':' . :
      :: ''.. :' .:'':.
       :: . ': .: ..' . '.
       ': ''''' .: .:::::''' :.
       :: .:': :
     .: : .:' :
    .' '' '' :
   :' :
  : :
.' :
: ' :'
: .:
' : .:
                   ' :
: .:
: .:
: .'
'. :'
  :. .'
   '. .:'
    ':. .:'
      ':. .:'
         ''..........''

My solution relies on having RMagick do all the work. Here's the output for the test image:

···

+-------------------------------------------------------------------------+

                     .::+====+:: |
                 .:==o======ooo*oo+. |
                +oo=====++++===oo***+ |
              :oo==++++===++==ooooo*^*. |
             :oo====++++====oooooooo*^* |
            .oo=====++++========ooo**^^o |
           .ooo=====++++++======ooo**^^%: |
          :*oo*o==============oooo****^^^. |
         :ooo$WW^===========oooo****^^^^^= |
         ooo*WWW%=========oooo^^*^**^^^^^^ |
         oooo=o::o=====oooo*%WWW$^^*^^^^*^: |
         =ooo=:+====ooooo**o^WWW$***^****^: |
         .*o*o*ooooo==ooo*^*+====o*^*****^. |
          :o%$$$$$WW$$$%%^^^^**********^^= |
           .oWWWWWWWWWWWWWW$%%^**o****^^= :::::: |
             %$$$$$$$W$$W$WWWW$^****^^o. ...::::::::==: |
             =WWWW$$$W$$$$WW$$%^^****+. .........:::::::::::::::::=o+ |
             :$WWWWWWWWWWWW%^****^%%%%%^^**oo====++:::::::::::::::+=o+ |
          :+oo*$$WWWWWWW$%^*^^^^^%$$$%%%^**o===+:::::::::::::::::++==o: |
        .:====o*^%$$$$$%^^%%^^^^%%%%%%%^^**o===+::::::::::::::::::===oo |
      .:+++++==o*^%%%%%%$%%%%^^^^%%%^^^**oo===++:::::::::::::::::+==ooo |
    .:+::::+++=oo*^%%%$%%%%%^^^^^*****ooo===+++::::::::::::::::++===oo= |
   :++::::::+++=oo*^%%%%%%^^****ooooo=====++:::::::::::::++:::++====o*. |
  :+::::::::::+===o**^^^^**ooo=====+=+++++::::::::::::+::==++++===ooo+ |
:+::::::::::::+++==oooooo====+::::+:::::+::::+::++::+::+==++=====oo= |
.+::::::::::::::::++=+=====+::::::+:::::+::::+:::+:::+++========ooo= |
:+::::::::::::::::::+:++++::::::++::::::::::+:::++:++==========ooo+ |
.++++:::::::::::::::::::::::::::+:::::+::::+:::++++===========oooo: |
.++++::::::::::::::::::::::::::::::++:+::+=+++==============oooo=. |
+++++++::::::::::::::::::::::++::++::+==+=+===========o===ooo=: |
:==++++::::+:::::::::+:+:::::::::+++===++=============ooooo=: |
.===++++++++++::+++::+++:+++++::+===++====o==========o=o==:. |
:=======+++++++++++++++++:++===============oo====oo=o==:. |
  :====================++++++==+=========o=====ooo====: |
   .==================================ooooooo=oo===+: |
     :+=============================oooo=o==oo==::. |
       ::==========================o====oo===::. |
          ::++==============+===========+::. |
             ..:::++++==++=+++++++++::.. |
                   ....:.::::::... |

+-------------------------------------------------------------------------+

require 'RMagick'

CHARS = ['W', 'M', '$', '@', '#', '%', '^', 'x', '*', 'o', '=', '+', ':', '~', '.', ' ']
FONT_ROWS = 8
FONT_COLS = 4

img = Magick::Image.read(ARGV[0] || "Flower_Hat.jpg").first

# Resize too-large images. The resulting image is going to be
# about twice the size of the input, so if the original image is too
# large we need to make it smaller so the ASCII version won't be too
# big. The `change_geometry' method computes new dimensions for an
# image based on the geometry argument. The '320x320>' argument says
# "If the image is too big to fit in a 320x320 square, compute the
# dimensions of an image that will fit, but retain the original aspect
# ratio. If the image is already smaller than 320x320, keep the same
# dimensions."
img.change_geometry('320x320>') do |cols, rows|
  img.resize!(cols, rows) if cols != img.columns || rows != img.rows
end

# Compute the image size in ASCII "pixels" and resize the image to have
# those dimensions. The resulting image does not have the same aspect
# ratio as the original, but since our "pixels" are twice as tall as
# they are wide we'll get our proportions back (roughly) when we render.
pr = img.rows / FONT_ROWS
pc = img.columns / FONT_COLS
img.resize!(pc, pr)

img = img.quantize(16, Magick::GRAYColorspace)
img = img.normalize

# Draw the image surrounded by a border. The `view' method is slow but
# it makes it easy to address individual pixels. In grayscale images,
# all three RGB channels have the same value so the red channel is as
# good as any for choosing which character to represent the intensity of
# this particular pixel.
border = '+' + ('-' * pc) + '+'
puts border
img.view(0, 0, pc, pr) do |view|
     pr.times do |i|
         putc '|'
         pc.times { |j| putc CHARS[view[i][j].red/16] }
         puts '|'
     end
end
puts border

Hi,

I have a solution written five years ago by Brian Fundakowski Feldman. Is
that allowed?

This code, which is not mine, uses the GD library.

This is not my code:

http://www.dave.burt.id.au/ruby/img2ascii.rb

Cheers,
Dave

Hello Everyone,

I went into this quiz using the following approach. I split the image
into pieces and find for each piece of the image the letter most
similar to this piece. I did it all with image magick. There is room
for improvement in the distance function, but it works ok. I'm sure it
is the slowest solution so far, but it works.

You can find the sourcecode and examples at

http://ruby.brian-schroeder.de/quiz/asciiview/

best regards,

Brian

. _,uuuuu,_
. _u:EEEEEEEEEE{{[p,_
. _:EEEEEEEEEEEEEEE{{[Ou
. :EEEEEEEEEEEEEEEE{{{{[O3_
. UEEEEEEEEEEEEEEEE{{E{{{[O3_
. UEEEEEEEEEEEEEEEEEEEEE{{[S3B
. ;{EEEEEEEEEEEEEEEEEEEE{{[SO3B$
. ;{{{EEEEEEEEEEEEEEEEEE{{[[O3333u
. {[[SQQ{EEEEEEEEEEEEEEE{{[[OO3333B
. E{{[###${EEEEEEEEEEEE{{[SSSS333333q
. E{{{###PEEEEEEEEEEE{SSQQ3333O333333
. {{{{ " LEEEEEEEE{{[S$####$333333333
. {{{{{:cEEEEEE{{{[[SZZ####Z3O3333OS3
. F{{{{{{EEjjEEE{[SO35EEEFEEOO3OOOO33
. F{]###########QQ3993SSSOSOO[[OS33~
. "f################$Q3O[[[[OSS33~ L-F"FL
. I#IIII#############Q[SSOO33P" L–" FE.
. P######$##IIII####T3SS333P' LL—F -EEU
. ##############T3OOO3OOQ$$$9SSUUUUEEEEEEF- -EEEE
. .;{[I##########TS3333S3$IIII$$B3O[{EEEEEFF -EEEE{
. LEEEE{O#$I#####@BBB33333$$$II]$$B3O[{EEEEEF- -EEEE{L
. LEEEEEEE[O3$$$$$$$$$$$$9BB$$$$$$@B3O[{EEEEEE-- --EEEEE{{
. LEEEEEEEEEE[3B$$]I]]$$$$$BBBBBBB333O[[{EEEEEEF-- —EEEEEEE{{
. LEFFFFFFEEEEE{[3B$$]]$$$$B333OOO[[[{{{EEEEEEEEFF .EE–EEEEEEEE{{"
. -FFF-- --FEEEEE{[3B@@@@@B33O[[{{EEEEEEEEEEEFFF L E .LEEEEEEEEEEEE{{
. -FFFF- -FFEEEEE{[O22OOO[[{EEEEEEEEEFFFEEF — LE -F .EEEEEEEEEEEE{{
. LEF— --FFEEEEEEEEEEEEEEEFFF-FEF EE LE LE" -E EEEEEEEEEEEE{{"
. EEE— --FFFEEEEEEEEEEEFF LEF LE LE -EE LEEEEEEEEEEEEEE{{"
. EEEEEF- —FFEEEFEEFF -EE" -EF LEFL-EEEEEEEEEEEEEEEEEE{E"
. EEEE-F— --F-FFFFFF -EF LLE LLEFEEEEEEEEEEEEEEEEEEEE{{E
. EEEEEE--------- — --- LE LLEFFLEEEEEEEEEEEEEEEEEEEEEEE{{EF
. EEEEEEEEE–F------ - -L–LLLLLEEELLEEE-LEEEEEEEEEEEEEEEEEEEEEEEE{EE"
. FEEEEEEEEEEEE-----L-LLEEEEFF" .""FF"LEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
. .EEEEEEEEEEEEEEEEEEEEEEEEEELLLEELLLEEEEEEEEEEEEEEEEEEEEEEEEEEEEF
. .FEEEEEEEEEEEEEEEEEEEEEEEEEEEFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEF
. FEEEEEEEEEEEEEEEEEEEEEEEELLEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEF
. FEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
. "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE{{E{EEEEEEEEEF"
. "FEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE{EEEEEEF"
. FFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFF"
. "FFEEEEEEEEEEEEEEEEEEEEEEEEEEEFFF"
. "FFFFFFEEEEEEEEEEEEEEFF"
. FF"""""

. _yv*/^^^^^^^/#Yy_
. y#^ '^#y
. y# ^#,
. _#^ Ty
. _# #y
. # ,- #_
. #^ #
. _#' ^g
. y# _Y/Xy #
. # # Tg ^$
. # #,^ y^ y**v_ #
. $ ###^ # _. # #
. # ^ _$_'_,# #
. #y _yyyyyyv*gyy_ ^###IIP #
. #y#$ ^ ^P*yy_ '' yf ,yvy_
. ^#$ ^P*y_ y# _y#^^ ,^#y
. '# ^P/*+ ,_ _T* _#^ __yv*P^ ' ^#_
. Ty~/**^^M ^P**#^v/^y# _g#yyyyyyyyvY*#P^^ #y
. y# '^rr**~'y#^^ _vP^' #_
. y#P^ #P_ y#^ T Y #
. _#^ ^#C/xvv-_yYP' ^$
. y#^ ^^Pr/~^' #
. _#^ #
. g^ yT
. #^ # #
. # F ^ $^
. #' _P @ # g # y^
.y^ ,^ / g ^ y^
# v y^
.# _/ y _ #^
.# Y^ _. , ,#'
.# r^ _^ g^
.# r/ Yr *^ _x ' y#
.^y _ *' _- y#^
. # __ r _#^
. # '^ ' ' y#^
. ^# - y#^
. #y _ _YP'
. ^#, r _y#^
. ^#y r _v#^
. ^#y_ -x `~ -r _y*P^
. ^/*y_ ~/***r__yY/^^
. ^^P**YvyyyyyyyyyvvY*/P^^

···

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Hi,

i'm completely new to ncurses, so could someone with more exprerience (or another OS) try this and tell me whats happening?
On windows all the colors are very pale (are there consts for lighter
colors?)

···

-----------------------------------------------------------------------
require 'RMagick'
require "ncurses"

Ncurses.initscr
puts "Usage: #{$0} <img> [size]" or exit if !ARGV[0]
puts "Sorry, no colors!" or exit unless Ncurses.has_colors?

img, size = Magick::ImageList.new(ARGV[0]), (ARGV[1]||40).to_f
factor = [size*2/img.rows, size/img.columns].min
img.resize!(img.columns*factor, (img.rows*factor*0.5).round)

COLORS =
   [[Ncurses::COLOR_BLACK, [0, 0, 0]], [Ncurses::COLOR_RED, [1, 0, 0]],
   [Ncurses::COLOR_GREEN, [0, 1, 0]], [Ncurses::COLOR_BLUE, [0, 0, 1]],
   [Ncurses::COLOR_YELLOW, [1, 1, 0]], [Ncurses::COLOR_MAGENTA, [1, 0, 1]],
   [Ncurses::COLOR_CYAN, [0, 1, 1]], [Ncurses::COLOR_WHITE, [1, 1, 1]]]

GRADIENT = [[0, ' '], [50, ':'], [100, '|'], [150, 'I'], [200, '#']]
COLORMAP = {}

COLORS.size.times do |bg|
   COLORS.size.times do |fg|
     next if fg == bg
     i = (bg*COLORS.size) + fg
     Ncurses.init_pair(i, COLORS[fg][0], COLORS[bg][0])
     GRADIENT.each do |gr, c|
       r = COLORS[fg][1][0] * gr + COLORS[bg][1][0] * (255-gr)
       g = COLORS[fg][1][1] * gr + COLORS[bg][1][1] * (255-gr)
       b = COLORS[fg][1][2] * gr + COLORS[bg][1][2] * (255-gr)
       COLORMAP[[r, g, b]] = [i, c]
     end
   end
end

#(16*16*4).times do |i|
# Ncurses.stdscr.attrset(Ncurses.COLOR_PAIR(i))
# Ncurses.stdscr.mvaddstr(i/16, (i%16)*4, 'TEST')
#end
#Ncurses.refresh

pixels = img.get_pixels(0, 0, img.columns, img.rows)
img.rows.times do |y|
   img.columns.times do |x|
     p = pixels[y*img.columns + x]
     r, g, b, best, dist = p.red, p.green, p.blue, -1, 255
     COLORMAP.each do |k, v|
       d = Math.sqrt((r-k[0])**2 + (g-k[1])**2 + (b-k[2])**2)
       (best, dist = v, d) if d < dist
     end
     Ncurses.stdscr.attrset(Ncurses.COLOR_PAIR(best[0]))
     Ncurses.stdscr.mvaddstr(y, x, best[1])
   end
end

Ncurses.refresh
-----------------------------------------------------------------------

maybe someone can help..

cheers

Simon

I'm happy to submit my first ruby quiz solution. I really liked the RMagick
library. It made this pretty easy.

the code:
require 'RMagick'

class ImageToAscii
@@ascii_pixel = [ Array.new(10, '#'),
Array.new(35, '.'),
Array.new(5, '\\'),
Array.new(15, '-'),
Array.new(20, '*'),
Array.new(15, '+'),
Array.new(20, ':'),
Array.new(20, '/'),
Array.new(30, '='),
Array.new(30, '|'),
Array.new(30,'@'),
Array.new(30, ' ')].flatten!
def initialize( image )
@image = image
end
def convert
prepare_image
translate_pixels
end
def translate_pixels
pixels = @image.get_pixels(0, 0, @image.columns, @image.rows)
new_pixels = pixels.map { |pix| to_ascii pix.intensity}
0.upto(@image.rows) do |row|
new_pixels.insert( (row*@image.columns+row), "\n")
end
new_pixels
end
def prepare_image
@image = @image.blur_image.blur_image.scale(40,40)
end
def to_ascii( index )
@@ascii_pixel[index]
end
end

img = Magick::ImageList.new(ARGV[0])
converter = ImageToAscii.new(img)
puts converter.convert.to_s

the output:
from ducky.png

@@|||@
@||||||==@
@||||||||==|
@|||||||||===@
>>>>>>>>>>>===
@|||||||||||==/@
>>>>>>>>>>>===/=
>==|||||||||===//
==\/|||||||====//@
@=/.+||||||=====//|
@=|||||||==+.+==/==
@==|||||===*\:=====
==========|||====|
>:**-**://=======@
=-------*:=====| @@@@
@*-**-----+==== @@@@@|@
*--*-**-*/===@ @@@@@@@@@||
+\\\\\-:===:://==|||@@@@@@@@|||
@|/*-\\-:/=//++:/==||@@@@@@@@@|||
@||=/+*+:////::::/=|||@@@@@@@@@|||@
@||||=/::::://////==|||@@@@@@@@@|||@
@@@|||=/:++:///=====|||@@@@@@@@@|||=@
@@@@@|||=/:://====|||||@@@@@@@||||||=
>@@@@@||===/===|||||||@@@@@@@||||||||
@@@@@@@@|||===|||@|@@@@@@@@@@@||||||=
>@@@@@@@@||||||@@@|@@|@@|@|@|||||||||
@|@@@@@@@@@@|||@@@|@@@@@@@@||||||||||
@||@@@@@@@@@@@@@@@@@@@@|@|||||||||||@
@||@@@@@@@@@@@@@@@@@|||||||||||||||@
@||||@@@@@@@@@@||||||||||||||||||||
>>>>>@|@@@@||@@@@@|||||||||||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@|||||||||||||||||||||||||||||@
>>>>>>>>>>>>>>>>>>>>>>>>>>>>@
@|||||||||||||||||||=||||||@
@|||||||||||||||||=|||||@
@||||||||||||||||||||@
@||||||||||||||||@
@@||||||||||@@
@@@@@@

and from tomb-raider.png:

........................................
........................................
................................*.......
....................:.............*.....
..........--......../-+-..........:.....
.........\--.......*|+=*-.\.......\*....
.........**|:...#..-|:=/+-..--.....*....
.........**@=.......|/=||=-*=|:....*....
.........**@=.......://|@|=|||=\...*....
.........*-@=......./==||||@||/....+....
....#..-#.-@=.......==|||||||=/-...-....
....#.--***@|........==||||===/:*..+....
.....*:+-|*@|........+==||=/====/...-...
....====:|-@|.........==/+===||=|..-\...
..-*==|||=-@|-#.......\-../|=||==:..*...
..**||@@@=-||*....\.......-|==+**+..-...
..-+|@@@|=-/*............*|/\.#.....*...
...-|@@||*..............+:.-://::-*.*...
.\..||||=.............\-../=====//-**...
....+==*......#......\-.-===|||==/+-*...
.\..................\../@|||@||===:-*...
.\\....-.\........-...*@|||@@||===*-*...
....#.:|||...........\|||||||||==/.--...
....../|@|/.........*||||@@@||==/..--...
......+=@@=......../|||@@@@||=/*...\+...
.......||@|/.....\=|||@@@|||=-.....\\*#.
.......==|@=+...*=|||@@@|||*.........:..
.......*=|||=*.:=|||@@|||/.#.....\..\/-.
......../=|||=/==|@@||||+........:..-/+.
........-==|||=|||||||/.........\=-.\=/.
.....\.../=|||||||||=-........\\=/\..=..
.....\...\=|||||||/-..........**=*-.:*..
.....\..../|@@@|=:...........--=+:+\/...
......\...*==/*.++...........-+/*+:*+...
......\.........:*...........+/--++.-...
......\........./*...........++-**......
...............-/*...........//-*.......
....#.........\.-.............|-........
....#.........-.*.............:+\.......
................+.......-......=:.......

Thanks for letting me play too.

Anthony Moralez

I never participate in these, but this one is tempting.

Ah, why not? :slight_smile: We do try to have a little fun.

Perhaps that means you need to send in a problem *you* can't resist! :wink:

What about ANSI color? :wink:

Very clever. I didn't think of that...

James Edward Gray II

···

On Oct 7, 2005, at 6:24 PM, Hal Fulton wrote:

Hal Fulton wrote:

Ruby Quiz wrote:

This week's Ruby Quiz is to create a tool that will allow you to preview an
image file at the command-line in pure text.

Your program will need to read in an image, in whatever format you want to
support, and respond with a text representation of the image that fits in the
terminal.

I never participate in these, but this one is tempting.

Might even make a few bucks, no?

http://www.artima.com/forums/flat.jsp?forum=123&thread=130735

James

···

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

Hi,

here is my attempt of solving this weeks quiz:

[snip]

sample output:

         .:'''''''.
        .: :.
       .: :.
       : :
      :' ':
     .: :
     : .':. ::
    :'.' : .. ':
    : :..' :' ': :
    :. ' : .: :
    ': '::'':.. ':' . :
     :: ''.. :' .:'':.
      :: . ': .: ..' . '.
      ': ''''' .: .:::::''' :.
      :: .:': :
    .: : .:' :
   .' '' '' :
  :' :
: :
.' :
: ' :'
: .:
' : .:
                  ' :
: .:
: .:
: .'
'. :'
:. .'
  '. .:'
   ':. .:'
     ':. .:'
        ''..........''

Wow, I really like that! Too cool.

Here's the code used in the quiz:

#!/usr/local/bin/ruby -w

unless ARGV.size == 1 and File.exists? ARGV.first
     puts "Usage: #{File.basename($0)} IMAGE_FILE"
     exit
end

require "RMagick"

text = %w{. : - ^ ! * + " = % o # \\ $ < &}

image = Magick::Image.read(ARGV.shift).first

image = image.quantize(text.size)
image.scale!([39.0 / image.columns, 20.0 / image.rows].min)
image = image.quantize(text.size)

pixels = Array.new
0.upto(image.rows) do |y|
     0.upto(image.columns) do |x|
         pixel = image.pixel_color(x, y).intensity
         pixels << pixel unless pixels.include? pixel
     end
end
pixels.sort! { |a, b| b <=> a }

0.upto(image.rows) do |y|
     0.upto(image.columns) do |x|
         2.times { print text[pixels.index(image.pixel_color(x, y).intensity)] }
     end
     puts
end

__END__

James Edward Gray II

···

On Oct 9, 2005, at 4:56 PM, Simon Kröger wrote:

I'm surprised how easy this Quiz was because of ImageMagick and
RMagick (based on the other submissions, I didn't try it.) Kudos to
the developers of those projects (though I imagine only the RMagick
developer will be reading this.)

Of course you quiz developers deserve kudos for your clever solutions
using RMagick.

I wonder how long the code would be for a solution that did NOT use
RMagick or any other image library? Maybe future submissions will
answer this question for me...

Ryan

I do believe I got pWn3d!!1!... Nice work, Brian.

I think my solution is probably slower, though :-). I'm too used to
doing this kind of thing in C/++.

···

On 10/10/05, Brian Schröder <ruby.brian@gmail.com> wrote:

I went into this quiz using the following approach. I split the image
into pieces and find for each piece of the image the letter most
similar to this piece. I did it all with image magick. There is room
for improvement in the distance function, but it works ok. I'm sure it
is the slowest solution so far, but it works.

You can find the sourcecode and examples at

http://ruby.brian-schroeder.de/quiz/asciiview/

--
Rob

I never participate in these, but this one is tempting.

Might even make a few bucks, no?

Ruby Buzz Forum - Ruby Quiz Anthology on Its Way!

do all contributors get a free sample?
*grin*

+--- Kero ------------------------- kero@chello@nl ---+

all the meaningless and empty words I spoke |
                      Promises -- The Cranberries |

+--- M38c --- http://members.chello.nl/k.vangelder ---+

Indeed. I only found RMagick two weeks ago, but it impressed me enough to make the quiz. It's a bit of a bear to get installed (because of ImageMagick, not the Ruby bindings), but worth the effort.

I second the thanks to the developer for giving us such great tools to work with!

James Edward Gray II

···

On Oct 9, 2005, at 6:57 PM, Ryan Leavengood wrote:

I'm surprised how easy this Quiz was because of ImageMagick and
RMagick (based on the other submissions, I didn't try it.)

James Edward Gray II wrote:

Wow, I really like that! Too cool.

Thanks, yes it turned out better than expected.

                                    .
                                 . ' ::
                            .. : ':
             .. :: ' '.
          : '': :. . ::
             '' :: :' . ':
          :: :: :: :... . :.
          ': :: . . :: ':':: :':. :
           : ::: :' : . ::' : .:: ::
      :' .': ':: : : : '' :: ':
      : :: : '' ' ': .
      ' :. :: : : : . ... :: . :
    ..:': : :: ' ':...: ' :. . :
    :' ' :: :: '''' : .: ': ' :.
  : ::'.' :: :: : ': ::::::: '
  ' :' :: .:' .::'' ' ::
    : : : '..: ' .:' ....... :. :
    :: .:' . ' .'' ' '. '.:
     :::''' .:' .' . . '. ::
    . : .:' .:' .. . .: ::
     . '' .:' :' ' :' ::
     ' .::': .' :' .: ::
       ::..': : .' .:' . :
       ': :.:. : .:' ..:'' : :.
        :. :::. .:' .:'' : ':
    . ': ''.:. ' .:' .:' . :.
   . :. :::. .:' .:' . ::
          : : ': .:' : :::.
        . ': '.'' .::' : :: ::
         . ': . ..:' : :' .:
       ' ::' ..:' : .: .: .:
         ' :.:::'' : ' : :. :
          '. ' :: .::' ':' :
          : ' :' '.. .:
        ' ': :. .: :'
             . : .' :
             '. : .: .... . :.'
              ' ' :: : ::

Unfortunately my console has another aspect ratio than most mail readers (more like 1.5/1 than 2/1) so i had to tweak it a bit for the image above.

the original is here:
http://perso.wanadoo.fr/psylo-vision/_images/wallpapers/_first/Tomb-Raider-cot�.jpg
(i made no other optimisation than choosing a suitable region)

cheers

Simon

[snip]
>
> You can find the sourcecode and examples at
>
> http://ruby.brian-schroeder.de/quiz/asciiview/

I do believe I got pWn3d!!1!... Nice work, Brian.

Thank you, rob. Though I can't decipher sms-code, though I hope it's
good for me :wink:

greetings,

Brian

···

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Kero <kero@chello.single-dot.nl> writes:

I never participate in these, but this one is tempting.

Might even make a few bucks, no?

Ruby Buzz Forum - Ruby Quiz Anthology on Its Way!

do all contributors get a free sample?
*grin*

+1 :smiley:

···

+--- Kero ------------------------- kero@chello@nl ---+

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Contributors of quizzes and code used in the book will be contacted very soon now...

James Edward Gray II

···

On Oct 9, 2005, at 7:26 AM, Kero wrote:

I never participate in these, but this one is tempting.

Might even make a few bucks, no?

Ruby Buzz Forum - Ruby Quiz Anthology on Its Way!

do all contributors get a free sample?